Ionic 핵심 개념

Ionic 앱 개발이 생판 처음이신 분들을 위해, 프로젝트 뒤의 핵심 철학, 개념, 도구에 대한 고차원의 이해를 하면 도움이 될 수 있습니다. 복잡한 주제에 들어가기 전에, Ionic 프레임워크가 무엇인지, 어떻게 작동하는지와 같은 기초를 다루겠습니다.

UI 컴포넌트

Ionic 프레임워크는 애플리케이션을 만드는 조각으로 제공되는 재사용 가능한 요소인 UI 컴포넌트 라이브러리입니다. Ionic 컴포넌트는 HTML, CSS, JavaScript를 사용하여 웹 표준으로 만들어졌습니다. 컴포넌트는 미리 만들어진 것이지만, 고도의 커스터마이징이 가능하여 앱은 쉽게 고유의 컴포넌트를 만들 수 있고, 고유한 외관과 느낌을 갖게 합니다. 더 자세히 말하자면, Ionic 컴포넌트는 전체앱에 걸쳐서 외관을 바꿀 수 있는 테마 적용이 쉽습니다. 외관에 대한 커스터마이징 정보는 테마 파트를 참고하세요.

플랫폼 지속성

플랫폼 지속성은 다중 플랫폼에서 앱 개발자가 같은 코드 베이스를  사용할 수 있게 하는 Ionic 프레임워크의 내장 기능입니다. 모든 Ionic 컴포넌트는 앱이 실행되는 플랫폼에 맞는 외관으로 표시됩니다. 예를 들어, iPhone과 iPad와 같은 Apple 장치에서는 Apple의 고유 iOS 디자인 언어를 사용합니다. 비슷하게, Android 장치에서는 Material 디자인이라고 불리는 구글 디자인을 사용합니다.

이러한 플랫폼 사이의 미묘한 디자인 변화를 통해 사용자는 친숙한 앱 환경을 제공받게 됩니다. Apple의 앱 스토어에서 받은 Ionic 앱에서는 iOS 테마로, Android의 플레이 스토어에서 받은 Ionic 앱은 Material 디자인 앱을 사용할 것입니다. 웹 브라우저에서 Progressive Web App (PWA)으로 표시되는 앱에서  Ionic은 기본적으로 Material 디자인 테마를 사용할 것입니다. 더 나아가, 어떤 플랫폼에서 특정 시나리오 하에 무엇을 쓸지는 모두 설정 가능합니다. 플랫폼 지속성에 대한 자세한 정보는 테마에서 찾아보세요.

탐색

지금까지의 웹 앱은 사용자가 페이지 앞으로 진행하고, 뒤로 가기 버튼을 눌러 뒤로 탐색하는 선형 히스토리를 사용해왔습니다. Wikipedia에서 돌아다니는 것을 예로 들면, 사용자는 브라우저의 선형 히스토리 스택 상에서 앞이나 뒤로 이동하게 됩니다.

이와 대조적으로, 모바일 앱은 특화된 병렬, “비선형” 탐색을 주로 사용합니다. 예를 들어, 탭 인터페이스는 각 탭에 대해 구분된 탐색이 가능하게 하여, 사용자가 현위치를 유지하면서 탭 사이를 탐색하고 전화할 수 있게 합니다.

Ionic 앱은 웹 개발자들이 친숙한 브라우저 스타일의 탐색 개념도 지원하는 한편, 병렬 탐색 히스토리를 지원하는 것도 포함하여 이러한 모바일 앱 탐색 접근을 받아들였습니다.

Angular와 @ionic/angular로 개발된 앱에 대해서는 모든 Ionic 4 Angular 앱에 처음부터 따라오는 Angular 라우터룰 사용하기를 권합니다. 이전 버전의 Ionic은 고유의 커스텀 라우터를 탑재하였지만, 최고의 도구와 개발자 경험을 제공하기 위해서 이제 프레임워크의 권장 라우터를 사용하게 되었습니다.

네이티브 접근

웹 기술을 사용하여 빌드된 앱(Ionic 앱과 같은!)의 놀라운 기능은 데스크톱 컴퓨터, 폰, 태블릿, 자동차, 냉장고 등 모든 플랫폼에서 가상으로 구동될 수 있다는 것입니다.  Ionic 앱의 같은 코드 베이스는 웹 표준과 이들 플랫폼에서 공유된 공통 API에 기반하기 때문에 많은 플랫폼에서 작동 가능합니다.

가장 흔한 사용 케이스 중 하는 Ionic으로 앱 스토어와 플레이 스토어 양쪽에서 받을 수 있는 앱을 만드는 것입니다. iOS와 Android 소프트웨어 개발 키트 (SDK)는 어떤 Ionic 앱이든 렌더할 수 있는 “웹 뷰”를 제공하는 한편, 완전한 네이티브 SDK 접근도 가능하게 해줍니다.

Capacitor나 Cordova 같은 프로젝트는 Ionic 앱이 네이티브 SDK에 대한 접근을 제공하는데 널리 쓰입니다. 다시 말해, 장치의 가속도계, 카메라, GPS 등에 대한 네이티브 기능 접근을 가지면서도, 공통 웹 개발 도구를 사용하여 빠르게 앱을 빌드할 수 있다는 것입니다.

테마

코어 Ionic 프레임워크는 CSS 프로퍼티 (변수)를 제공하여 유연함(flexibility)을 가진 CSS로 만들어졌습니다. 이것이 웹 표준을 준수하면서 앱을 엄청 빠르게 디자인할 수 있게 했습니다. 몇 가지 뛰어난 기본값으로서 개발자에게 색상 선택지를 제공하면서도, 그걸 새로 구현하여 브랜드나 회사의 디자인을 만들거나 원하는 색상 팔레트로 만들어내는 것 또한 권장합니다. 앱의 배경 색상 부터 텍스트 색상까지 모두 사용자 지정이 가능합니다. 테마에 대한 자세한 정보는 테마 문서를 참고하세요.

Ionic Framework이 무엇입니까?

Ionic Framework는 (HTML, CSS, 자바스크립트와 같은) 웹 기술을 이용한 고성능, 고품질 모바일 및 데스크톱 앱을 구축하기 위한 오픈 소스 UI 툴킷입니다.

Ionic Framework는 프론트엔드 사용자 경험이나 앱의 UI 상호 작용 (컨트롤, 상호작용, 제스쳐, 애니메이션)에 중점을 둡니다. 배우기 쉽고, Angular와 같은 다른 라이브러리와 쉽게 잘 통합되거나, 간단한 스크립트를 사용하고 프론트 프레임워크 없이 단독형으로 사용될 수도 있습니다.

현재 Ionic Frameworksms Angular와 React와 공식적으로 연계되며, Vue는 개발중입니다. Ionic Framework를 본격적으로 시작하기 전에 더 배워보고 싶은 분들을 위해, 기본을 살펴보는 비디오를 만들었습니다.

목표

크로스 플랫폼

단 한 개의 코드 베이스로 네이티브 iOS, Android, 데스크톱, 프로그래시브 웹 앱과 같은 멀티 플랫폼에 걸쳐서 작동하는 앱을 만들고 배포해보세요. 한 번의 작성으로 여러 곳에서 실행해보세요.

웹 표준 기반

Ionic Framework는 사용자 컨트롤과 쉐도우 DOM 등 현대 웹 API를 사용하는 HTML, CSS와 JavaScript 같은, 가장 믿을 수 있고 표준화된 웹 기술로 만들어졌습니다. 이 탓에, Ionic 컴포넌트는 안정적인 API를 갖고 있으며, 불안정한 단일 플랫폼 공급자가 아닙니다.

아름다운 디자인

깔끔하고 단순하며 기능적입니다. Ionic Framework는 모든 플랫폼을 막론하고 결과물을 아름답게 표시하고 작동하도록 디자인되었습ㅈ니다. 미리 디자인된 컴포넌트, 타이포그래피, 대화형 패러다임, 멋진 (확장 가능한) 기본 테마와 함께 시작해보세요.

단순함

Ionic Framework는 즐겁게 Ionic 앱을 만들고, 배우기 쉬우며, 웹 개발 기술을 가진 누구든지 접근할 수 있도록 복잡하지 않게 만들어졌습니다.

라이센스

Ionic Framework는 허용 가능한 MIT 라이센스 하에서 배포되는 무료 오픈 소스 프로젝트입니다. 이는 개인과 상용 프로젝트에 무료로 쓰일 수 있다는 것입니다. MIT는 jQuery, Ruby on Rails와 같은 유명한 프로젝트에도 똑같이 쓰인 라이센스입니다.

이 문서 내용(ionic-docs 저장소에 있는)은 Apache 2 라이센스로 보호됩니다.

Ionic CLI

공식적인 Ionic CLI 또는 명령줄 인터페이스는 빠르게 Ionic 앱을 구축하고 Ionic 개발자에게 유용한 수많은 명령을 제공합니다. Ionic의 설치와 업데이트 뿐만 아니라, CLI에는 내장 개발 서버, 빌드 및 디버깅 도구 등을 포함합니다. Ionic Appflow 사용자라면, CLI는 클라우드 빌드와 배포까지 수행하고, 여러분의 계정을 관리하는데도 쓰일 수 있습니다.

Framework 호환성

과거 버전의 Ionic은 Angular와 깊이 묶여 있었지만,  V4 프레임워크는 Angular와 같은 최신 JavaScript 프레임워크와 결합된 단독 웹 컴포넌트 라이브러리로 작동하도록 재구축되었습니다. Ionic은 비록 완전한 웹 컴포넌트 지원을 위해 shim이 필요하지만, 성공적으로 React와 Vue 같은 대부분의 프론트엔드 프레임워크에 쓰일 수 있습니다.

JavaScript

Ionic 4의 주요 목표 중 하나는 컴포넌트를 제공하기 위한 단일 프레임워크에 대한 강한 의존을 제거하는 것이었습니다. 즉, 코어 컴포넌트가 웹 페이지에서 스크립트 태그만으로 단독 작동이 가능하다는 것입니다. 프레임워크와 작동하는 것이 대규모 팀과 대규모 앱에서 최적일 수 있지만, WordPress와 같은 단일 페이지 내용에서도 단독 라이브러리로 Ionic을 사용할 수 있다는 것입니다.

Angular

Angular는 Ionic을 쓸만하게 만든 존재였습니다. 코어 컴포넌트가 단독 웹 컴포넌트 라이브러리로 작동하도록 쓰였지만, @ionic/angular 패키지는 Angular 생태계와의 통합을 용이하게 만듭니다. @ionic/angular는 Ionic 2/3에서 넘어온 Angular 개발자들이 기대하는 기능을 제공하며, Angular 라우터와 같은 코어 Angular 라이브러리와 통합합니다.

React

Ionic은 널리 쓰이고 있는 React 라이브러리에 대한 공식 지원을 제공합니다. Ionic React는 React 개발자들이 iOS, Android, 데스크톱을 타겟으로 하는 앱을 만들 수 있는 기존의 웹 기술을 사용할 수 있게 합니다. @ionic/react와 함께, 여러분은 네이티브 React 컴포넌트를 쓰는 기분으로 모든 코어 ionic 컴포넌트를 사용할 수 있습니다.

미래 지원

다른 프레임워크에 대한 지원도 곧 릴리즈될 것으로 기대됩니다. 현재 Vue에 대한 공식 바인딩이 개발되고 있지만, 일부 컴포넌트는 해당 프레임워크에서 즉시 작동 가능합니다.

Ionic Framework V4+

Ionic 프레임워크 V4는 성능, 호환성과 전체적인 확장성에 중점을 둔, 기저 기술과 프로젝트 가능성의 중요한 진보입니다. V4가 Angular와 @ionic/angular 패키지로 여전히 깊이 결합되긴 하지만, 이제는 프레임워크에 구애받지 않는데, 다시 말해 어떤 다른 JavaScript 프레임워크든지 (Vue, React, Preact 등), 또는 프레임워크가 없든지 작동한다는 것입니다.

웹 표준으로 이동하면서, V4는 Ionic 코어가 프레임워크 의존적인 모델에서 벗어나 현대 브라우저에서 지원되는 표준 컴포넌트 모델에 의존할 수 있게 됩니다. 더 빠른 로드 시간, 더 나은 성능, 적은 코드양을 보여줍니다.

Ionic Appflow

Ionic 앱의 생애주기 관리를 지원하기 위해, Ionic Appflow라고 하는, 개발앱을 위한, 오픈 소스 프레임워크와 별도의 상용 앱 플랫폼을 제공합니다.

Ionic Appflow는 개발자와 팀이 중앙화된 대시보드에서 네이티브 앱을 컴파일하고 라이브 코드 업데이트를 배포하는데 도움을 줍니다. 워크플로우 자동화, 단일 로그인(SSO)과 연결된 서비스와 통합에 대한 접근 같은 고급 기능을 위해 유료 업그레이드 옵션을 사용할 수 있습니다.

Appflow에는 Ionic 계정이 필요하며, 일부 기능을 가지고 놀고 싶은 사람들을 위해 무료 “스타터” 플랜도 있습니다.

생태계

Ionic Framework는 코어팀에 의해 풀타임으로 활발하게 개발되고 유지되고 있으며, 성장과 도입을 촉진하는 전세계 개발자와 기여자 커뮤니티에 의해 생태계가 조성되고 있습니다. 개발자와 크고 작은 회사는 Ionic을 사용하여 어디서나 실행되는 놀라운 앱을 빌드하고 제공합니다.

커뮤니티 가입

전세계 200여 개 나라에 수백만의 Ionic 개발자가 있습니다. 가입하는 방법은 다음과 같습니다.

  • 포럼: 질문하고 아이디어를 나누기 좋은 곳입니다.
  • 슬랙: 개발자들이 만나서 실시간으로 대화를 나누는 활기찬 곳입니다.
  • 트위터: 업데이트를 올리고 Ionic 커뮤니티의 내용을 공유하는 곳입니다.
  • GitHub: 버그를 보고하고, 새 기능을 요청하고, 이슈를 만드는 곳입니다. 풀 리퀘스트도 환영합니다!
  • 글 작성하기: 기술 블록그를 쓰고 Ionic 커뮤니티에서 여러분의 이야기를 나누세요.

chinachu와 Raspberry Pi 3+로 일본 지상파 TV 서버 구축하기

TV 서버가 필요한 이유

일본은 지상파 TV 채널이 크게 발달해있습니다. 우리 나라는 유선 방송을 돈 내고 보는 사람이 많은 것과 크게 다릅니다.

지상파 TV, 위성 BS, 프리미엄 위성 CS로 크게 세 가지 채널로 양분되며, 지역 동축 케이블 TV와 인터넷 TV는 크게 힘을 못 쓰는 구조로 알려져 있습니다.

그래서 화제를 노리고 나오는 신작 애니메이션이나 외화들은 지역마다 있는 지상파 TV에 나오기 위해 애를 쓰는 것이죠.

볼만한 건 심야에만 있다

하지만 한국에 소개되는 청소년 이상 일반 성인을 대상으로 한 애니메이션은 상당히 늦은 시각에 방송되고 있다는 것을 뒤늦게 알게 됩니다.

즉, 낮이나 저녁에 TV를 틀었는데 왜 일본 생활에서 생각했던 덕질을 못하냐는 의문이 드는 것이죠.

하고 있는 것은 앵무새 같은 시사 프로, 광고, 이른 시간이나 낮에는 어린이용 애니메이션이 대부분입니다.

편성표를 보면 신작 애니메이션의 경우 심야에 한 번 방송하고, 재방송조차 없는 게 대부분입니다.

일본인들은 심야 본방 사수가 어렵다 싶으면 TV에 하드를 연결하거나, 블루레이 레코더를 활용하여 어쩔 수 없이 예약 녹화를 하는 경우가 많습니다.

일반 재생기 녹화 기능은 저작권법에 따라 제한이 걸려 있다

그러면 그냥 그렇게 보면 되지 않냐고 생각하시겠지만, 녹화된 파일은 녹화된 장치에서만 유효합니다.

파일의 전송권을 크게 제약하는 것이죠. TV가 아닌 PC나 휴대기기에서 보고 싶다고 복사를 할 수가 없는 것입니다.

전용 기기에서 녹화한 파일은 암호화되어 있습니다.

TS 따기라고 부르는, MPEG 데이터만을 순수하게 담은 TS 파일을 추출할 수만 있다면, 컴퓨터에는 팟플레이어 등의 재생기로, 휴대 기기에서는 인코딩하여 보거나 최신 스마트폰에서는 역시 재생기 앱만으로 볼 수 있게 됩니다.

어디서나 라이브를 볼 수 있다

Chinachu 서버가 웹 서비스를 제공하므로, 호환되는 클라이언트나 브라우저로 접속해서 시청할 수 있습니다.

수신기에 내장된 튜너 하나가 동시에 채널 하나를 수신할 수 있으니, 튜너 독점에 주의해야 합니다. 자세한 내용은 후술합니다.

법적 제약 주의

신작 애니메이션의 방송 서두에 항상 하단에 나오는 인터넷 무단 전송에 대한 경고를 생각해보면, 이렇게 녹화한 것을 함부로 남에게 전송해서는 안 된다는 것을 쉽게 알 수 있습니다.

일반 PC는 안 되는가?

사실 우리가 사용할 소프트웨어는 오픈 소스이면서 리눅스 계열에서 큰 문제 없이 돌아갑니다. 즉, 여러분의 일반 PC로도 충분히 가능합니다.

다만, 다음과 같은 이유로 별도 장치를 활용하길 권합니다.

  • 전원을 계속 켜두고 예약 녹화 장비로 쓰기엔 전기료가 과합니다.
  • 윈도우 유저는 멀티부팅을 해야 해서 번거롭습니다.
    • Windows 10의 WSL Bash로 Ubuntu 등을 내부에 깔아서 쓴다고 해도 제약이 있습니다.
    • 바로 USB 장비를 인식하지 못한다는 것입니다. 우리가 아래에 준비할 준비물을 전혀 쓰지 못하므로 조건을 만족하지 못합니다.
    • Opera Virtual PC 무료 버전에 플러스팩을 깔아주면 USB 호환을 시킬 수 있습니다만, 매 번 부팅시마다 다시 연결해줘야 하며 꼭 장치 하나씩 말썽을 일으키니 추천하지 않습니다.

준비물

PC 역할을 할 Raspberry Pi 3+ Model B

라즈베리파이가 구동하려면 SD 카드도 필요합니다.

모든 것이 갖춰진 패키지도 판매중이니, 적당한 가격의 물건을 물색해봅시다.

다만, OS는 직접 설치해야할 가능성이 높습니다.

USB 지상파 TV 튜너

PX-S1UD라는 작은 기기가 가격이 그나마 저렴하고, 리눅스용 드라이버도 호환되어서 널리 쓰이는 듯 합니다.

널리 쓰이는 기기가 문제를 덜 일으키니 믿고 씁시다.

끝부분은 안테나 단자에 꼭 잘 연결합시다.

IC 카드 리더

SCR3310

IC 카드 리더기는 아래 B-CAS 카드를 읽을 수 있는 수단입니다.

B-CAS 카드

B-CAS 카드는 스크램블(암호화)된 일본의 방송 신호를 해석하기 위해 필수적인 물건입니다.

구하는 방법이 궁합니다. 원래 수상기에 같이 딸려 나오는 식으로 신품 구입시 손에 들어옵니다. 그러나 카드 슬롯 없는 제품도 있고, 중고로 팔 때 없는 경우가 많으며, 그냥 별다른 이유 없이 신품인데도 안 주기도 합니다.

별도로 정식으로 방송협회에 주문하면 약 3천엔이 날아갑니다.

아마존을 뒤져서 중고로 500엔에 구해봅시다.

빨간색과 파란색으로 나뉩니다.

  • 빨간색: 다기능. 위성 BS와 지상파 모두 디스크램블이 가능합니다.
  • 파란색: 지상파만 디스크램블 할 수 있습니다.

500GB 이상급의 하드디스크

녹화한 TS 파일은 압축되지 않은, 실시간 수신 내용 그대로를 담습니다. 비트레이트라고 불리는 초당 용량이 그대로 누적되는 것입니다.

FullHD 1080p 수신에 약 15Mbps1 남짓으로 방송 한 프로에 6기가바이트 하는 건 흔한 일입니다.

충분한 용량을 준비하되, 일정 주기로 인코딩하여 화질과 용량의 균형을 맞춰서 작게 만들면 더 많이 저장할 수 있습니다.

시작

Raspberry 운영체제 설치

이에 관해서는 관련 정보를 활용해보세요.  NOOBS OS 설치로 충분합니다.

Pi에서 인터넷에 연결되는 것을 확인하고 SSH나 실제 Bash 콘솔에서 시작합니다.

사전 준비

이제 위에 있는 USB 장비는 죄다 라즈베리파이에 연결합니다.

이하 박스에 있는 내용은 bash 콘솔에 쳐야할 내용입니다.

필요한 것들
sudo apt-get install -y vim samba ntp wget curl git make cmake zip
sudo apt-get install -y pcscd libpcsclite1 libpcsclite-dev libccid pcsc-tools
sudo apt-get install -y autoconf build-essential git-core libssl-dev libtool libboost-all-dev pkg-config yasm pkg-config

설치

PX-S1UD_driver_Ver.1.0.1.zip 백업본

튜너 드라이버 설치
mkdir ~/PX-S1UD
cd ~/PX-S1UD
wget http://plex-net.co.jp/plex/px-s1ud/PX-S1UD_driver_Ver.1.0.1.zip
unzip PX-S1UD_driver_Ver.1.0.1.zip
sudo cp PX-S1UD_driver_Ver.1.0.1/x64/amd64/isdbt_rio.inp /lib/firmware/
카드리더기 설치
sudo pcsc_scan

여기서 Japanese Chijou Digital B-CAS Card라는 문구를 확인할 수 있어야 합니다.

c44e16dbb0e2.zip의 백업본

arib25 라이브러리 설치
sudo su –
mkdir ~/tmp
cd ~/tmp
wget http://hg.honeyplanet.jp/pt1/archive/c44e16dbb0e2.zip
unzip c44e16dbb0e2.zip
cd pt1-c44e16dbb0e2/arib25
make clean && make
make install

arib25는 B-CAS 카드 표준에 맞게 읽을 수 있는 라이브러리로 추정됩니다.

recdvb-1.3.1.tgz의 백업본

recdvb 설치
cd ~/
mkdir ~/recdvb
cd ~/recdvb
wget http://www13.plala.or.jp/sat/recdvb/recdvb-1.3.1.tgz
tar xvzf recdvb-1.3.1.tgz
cd recdvb-1.3.1
./autogen.sh
./configure –enable-b25
make
make install
chinachu 설치 환경을 위한 npm n 구축
apt-get install -y nodejs npm
npm cache clean
npm install n -g
n 6.10.3  n 8.x
apt-get purge -y nodejs npm
apt-get -y autoremove

현재 chinachu 버전업으로 인해 npm 8 버전을 써야 하는 것으로 기억하는데, 오류 메시지가 떴을 때 최소 요구 사항을 확인하고 버전을 맞추면 됩니다.

node의 버전 확인
node -v

버전이 잘 표시되어야 합니다.

Mirakurun 설치

Mirakurun은 제조사 드라이버를 통해 튜너를 제어하는 소프트웨어입니다.

mirakurun 설치
sudo npm install pm2 -g
sudo npm install mirakurun -g –unsafe –production
sudo npm install rivarun -g
sudo npm install arib-b25-stream-test -g –unsafe
mirakurun 동작 확인
ps ax | grep Mirakurun

숫자로 PID가 잘 표시되면 OK입니다.

Tuner 설정
sudo nano /usr/local/etc/mirakurun/tuners.yml

여기 내용으로 다음과 같이 붙여넣습니다.

tuners.yml
– name: PX-S1UD-1
types:
– GR
command: recdvb –b25 –dev 0 – –

– name: PX-S1UD-2
types:
– GR
command: recdvb –b25 –dev 1 – –

갖고 있는 튜너는 하나지만 둘 다 넣어야 성공하였습니다. 원글은 분배기를 통해 두 개 튜너를 연결했습니다.

채널 설정

채널 수동 설정을 하고 싶으면 다음과 같이 입력하면 됩니다.

Channel 수동 설정
sudo nano /usr/local/etc/mirakurun/channels.yml

그러나 무엇이 잡히는지도 모르기 때문에 우리는 자동 설정을 할 것입니다. 안테나가 정상적으로 연결되고 튜너가 인식되어야 가능합니다. 아래 명령을 친 다음, 채널을 찾았는지 바로 명령 결과로 각각 뜨기 때문에 지켜보면 됩니다. 채널이 있을 법한 구간에서 오류가 지속적으로 난다면, 튜너를 재연결하고 재부팅해보세요.

Channel 자동 설정
curl -X PUT http://localhost:40772/api/config/channels/scan”

40772 포트는 Mirakurun 서버에 연결할 수 있습니다. 연결에 실패하면 Mirakurun의 재설치가 필요합니다. npm으로 설치했으니 node부터 올바르게 설치되었는지 필히 확인하세요.

Mirakurun 재시작
mirakurun restart

모든 변경사항을 적용하기 위해 재시작합니다.

EPG 수신에 대략 10분 정도 기다려준 다음에,

EPG 수신 확인
rivarun –list | sed ‘s/},/},\n/g’

이것을 입력하여 EPG 내용이 올바르게 받아지는지 확인합니다.

로그 로테이트 설정
sudo pm2 install pm2-logrotate
sudo nano /etc/logrotate.d/mirakurun
mirakurun 파일 내용
/usr/local/var/log/mirakurun.stdout.log
/usr/local/var/log/mirakurun.stderr.log
/{
daily
compress
rotate 7
missingok
notifempty
}

Chinachu 설치

Chinachu는 녹화 스케쥴 관리, 실시간 방송 스트리밍이 가능한 PVR 매니저입니다.

Chinachu 설치
adduser chinachu
su – chinachu
git clone git://github.com/kanreisa/Chinachu.git ~/chinachu
cd /home/chinachu/chinachu
./chinachu installer

여기서 설치 방법을 물어볼텐데, 1을 입력하고 엔터를 눌러서 1) Auto (Full)을 선택합니다.

시간이 매우 오래 걸리므로 대기합니다.

환경 설정

녹화 설정 파일 초기화 및 환경 설정 입력
echo “[]” > rules.json
cp config.sample.json config.json
nano config.json
config.json에서 Key값에 맞게 Value를 수정해야할 부분 (발췌)
“uid”: “chinachu”,
“recordedDir” : “./recorded/”,
“wuiOpenPort”: 10772,

uid에는 우리가 지금 만든 계정 이름을 넣어주시고 (여기서는 chinachu), recordedDir는 녹화 파일이 저장될 디렉토리입니다. 폴더 소유자 및 권한에 주의하세요.

포트는 웹에서 접속 가능한 곳을 지정하며 별도의 인증 기능이 빠져있으니 외부 접속에 유의해야 합니다.

chinachu의 로그 로테이트 설정

chinachu 로그 로테이트 설정
exit
nano /etc/logrotate.d/chinachu
chinachu
/usr/local/var/log/chinachu-operator.stderr.log
/usr/local/var/log/chinachu-operator.stdout.log
/usr/local/var/log/chinachu-wui.stderr.log
/usr/local/var/log/chinachu-wui.stdout.log
{
weekly
compress
rotate 4
missingok
notifempty
}

동작 확인

확인 후 마지막 단계에서 에러가 안 나면 Ctrl+C
su – chinachu
cd ~/chinachu
./chinachu service wui execute
데몬 설정 확인
exit
cd /home/chinachu/chinachu
pm2 start processes.json

프로세스 시작 후 10초 정도 대기한 다음 다음 명령을 입력합니다.

상태 표시 후 online 문구 확인
pm2 status
현재 설정 저장
pm2 save

향후 config.json의 수정을 한 다음에 할 일

설정 읽어들이기 위한 chinachu 재시작 방법
pm2 restart chinachu-wui chinachu-operator
로그 파일 위치 일람
/usr/local/var/log/chinachu-operator.stderr.log
/usr/local/var/log/chinachu-operator.stdout.log
/usr/local/var/log/chinachu-wui.stderr.log
/usr/local/var/log/chinachu-wui.stdout.log
EPG 수동 갱신 방법
su – chinachu
cd ~/chinachu
./chinachu update
브라우저로 접속하는 주소
http://(라즈베리파이 IP주소):10772/

이제 브라우저에 chinachu 화면이 정상적으로 뜨는 것을 확인할 수 있습니다.

Asus Zenfone 5z 개봉기

ASUS가 폰을 만듭니다.

그런 사실을 어째서인지 한국 사람들만 잘 모르고 있습니다. 당연한 일입니다. 출시한 적이 없는 해외폰이니까요.

하지만 저는 과거의 ASUS가 만든 폰을 직접 사용해본 적도 있습니다. 그건 바로 Asus Zenfone 5입니다.

그 때의 사용기를 어딘가 적진 않았지만, 지금 사진을 보니 참으로 각진 기묘한 디자인입니다.

뒤쪽 덮개를 열 수 있는데 배터리는 슬쩍 보임에도 아예 분리할 수 없게 고정되어 있었던 게 특징입니다.

또 듀얼심인데 3G 대응, 나머지는 무조건 2G(GSM)만 가능하여서, 3G HSPA+ 계열만 있던 한국에선 듀얼심으로 사용할 수 없었습니다. 한국에 GSM이 없거든요.

2014년 당시엔 괜찮았지만, LTE 시대에 들어오면서 GSM도 세대가 2단계 (또는 그 이상) 뒤쳐지다보니, 서비스를 중단하는 곳도 늘고 주파수는 실시간으로 용도 전환이 되며 입지가 좁아지고 있습니다.

그래서 듀얼심에 대한 환상도 와르르 무너졌던 기억이 있습니다.

LG Optimus LTE, Galaxy S3, ASUS Zenfone 5 (2014) 벤치마킹

Intel Atom Z2580 칩셋을 사용하고 있는데, x86에 arm 에뮬레이팅이 내장되어 있습니다.

그럼에도 일부 게임이 호환이 안 된 적도 있던 것 같습니다. 애매한 성능에 애매한 배터리, 적지 않은 발열로 요약되는 경험이었죠. 왜 가만히 냅둬도 혼자서 가끔씩 뜨겁게 불타올랐던 걸까 지금도 모르겠습니다.

깨알같이 5GHz WiFi 미지원도 단점이었죠.

ASUS Zenfone 5를 써봤는데, 4년 후 새로 산 폰도 ASUS Zenfone 5라니

제가 산 제품은 정확하게는 끝에 Z가 하나 더 붙은 건데, 이건 AP 성능 차이로 인한 라인업의 다른 것일 뿐, 실제 메인 스트림은 둘 다 같은 제품명입니다.

대략 정신이 멍해지는 네이밍 센스랄까 꼬여버린 족보라고 할 수 있겠습니다.

그래서 지금도 구글링하면 Asus Zenfone 5 (2014), Asus Zenfone 5 (2018) 이렇게 나뉩니다.

이름은 같지만, 많은 것이 달라졌습니다.

험난한 배송 과정을 드러내는 외부 박스를 벗기니 Zenfone 5z의 길쭉하고 작은 박스가 드러납니다.

박스를 위로 벗기면 사진을 좋아한다는 ASUS의 주장이 담겨있습니다.

기본으로 젤리케이스 투명을 하나 끼워줍니다. 중국산 폰은 빌트인 케이스 하나씩 끼워주는게 서비스인 것 같습니다.

그런데 ASUS는 대만산인데…. 흠…

심 트레이 클립도 나름대로의 스타일을 갖고 있는 것 같습니다.

그래서 잃어버리지 않으려고 하는데, 쉽지 않겠어요.

실리콘 케이스와 보증 서류를 치우면 비닐로 한꺼풀 덮여있는 본체가 드러납니다.

세로로 긴 폰이 불투명한 비닐로 포장되어 있습니다. 전원 버튼을 못 찾을까봐 비닐에 위치가 하이라이트되어 있습니다.

비닐을 벗기면 당연히 없어지겠지요.

상자의 아랫 부분을 열어 보면 프리볼트 0.5A 입력의 충전기(출력 5V/2A+9V/2A), 데이터 케이블, 이어폰, 이어폰 커널이 있습니다.

비닐을 벗기고 뒷면을 보면 빛이 납니다. 강화유리로 한꺼풀 덮기라도 했는지 미끈거리며, 지문은 마구마구 묻어납니다.

케이스가 없으면 나중에 허옇게 지문이 얼룩져 있어서 꼴보기 싫어하는 사람도 많을 것 같습니다.

가운데 LG 폰처럼 지문 인식 영역이 있습니다. 전에 쓰던 폰도 LG V20이라서 똑같은 위치에 지문 인식이 있었는데, 어느쪽이든 검지를 갖다대어 인식하기 편리합니다.

다만 차이가 있다면 전원 버튼 등의 역할을 하지 않는 고정된 영역에 불과하다는 것입니다.

버튼 같이 생겼지만, 안타깝게도 눌리지 않아요.

상단에는 별 것이 없습니다. 구멍이 하나 있는 건 통화시 배경 소리 녹음용 보조 마이크 같습니다.좌측면에도 별 것이 없습니다. 보조 마이크가 두 개라고 하던데, 여기에도 구멍이 하나 더 있긴 합니다.

유심을 삽입할 수 있는 트레이와 핀 구멍도 있습니다. 하이브리드 듀얼심이라 SIM 2에 MicroSD나 두 번째 SIM 카드 둘 중 하나만 넣을 수 있습니다. 보조 장비를 구매하여 SIM 카드를 외부로 연장시키는 도구를 쓰면 메모리 카드와 SIM 카드 두 가지를 활용할 수 있다고 하더군요.하단은 좌측부터 3.5파이 이어폰 단자, USB C-Type 포트, 우측에 모노 스피커가 있습니다.

그런데 특이하게도 수화 스피커로도 평시에 소리를 스테레오로 내고 있습니다. 대칭이 아닌 기묘한 스테레오 음향인 셈인데, 들어줄만 합니다.우측에는 위부터 볼륨, 전원 버튼이 간격을 두고 있습니다.

예나 지금이나 무게감 있는 로고명이라고 생각합니다. Powered by Android 라는 문구가 앞에 빠르게 지나갑니다. 부팅 속도는 결코 느리지 않은 편이에요.

알고보니 램 보존 부팅을 오래전부터 하던 제조사더군요. 최대 절전 모드와 유사한 방식이라고 합니다.

안드로이드 오레오 8.1의 순정이 어떠한지 잘 모르겠지만, 깔끔하게 다듬어진 UI로 보입니다. 당당히 한국어도 지원하고 있으며, 번역에 거슬리는 부분은 크게 드러나지 않습니다.

한국에 팔아도 욕먹지는 않겠어요.

아… 저런 오타는 이해해줘야 할까요. 긹! 이전 장치에 옮긴다는 표현도 이상하긴 하네요.

이 앱은 기존 폰에도 설치해서 Wi-Fi Direct로 연결하여 데이터 및 APK를 그대로 전송할 수 있습니다.

그러나 구글 백업의 복원과 동시에 진행하지 않기를 권합니다. 같은 앱 패키지를 깔 때 충돌나서 앱 이동 설치 작업이 도중에 중단되고 급기야 Wi-Fi Direct가 끊겨서 처음부터 다시 해야 합니다.

물론 옮겨진 부분까지는 그대로 넘어오기 때문에 남은 것만 선택하고 진행하면 되지만, 그게 선택이 날아가서 도중에 그만두면 다시 시작하기가 쉽지가 않아요.

앱 데이터가 옮겨지지 않는 것 같고 요즘 앱들이 자체 클라우드 로그인을 하면 하지, 백업을 대체로 거부하기 때문에 그냥 플레이스토어 들어갈 수고를 던다는 의미밖에 없긴 합니다.

기존 폰의 내부 저장소의 폴더를 싹 긁어올 수 있어서, 다운로드 폴더에 한가득 짐을 짊어지고 계신 분들도 기존 폰에서 유실되는 자료 없이 옮길 수 있다는 건 큰 장점입니다.

갤럭시처럼 USB Direct 케이블 연결도 지원하면 나무랄 데가 없겠어요.

런처 사진을 찍을까 했지만, 개봉기의 마무리는 게임 실행으로 끝냅니다.

아쉽게도 이 앱은 18대 9의 초와이드 화면을 지원하지 못해 오른쪽에 검은 레터박스가 드러나네요.

게임 및 퍼포먼스, 내부 소프트웨어에 대한 이야기는 다음편에 이어서 할까 합니다.

[번역글] 1. 인증서 투명성 (Certificate Transparency) 개요

인증서 투명성 개요

구글의 인증서 투명성 프로젝트는 모든 HTTPS 연결에 쓰이는 주요 암호화인 SSL 인증서 시스템의 결함을 수정합니다. 이 결함은 인터넷 연결의 암호화된 연결의 효용성과 신뢰도를 약화시키고 도메인 인증, 양 끝단 암호화, 그리고 인증서 인증을 통해 구성된 신뢰 체인을 포함한 TLS/SSL 구조의 심각한 손상을 가져올 수 있습니다. 이를 확인하지 않고 방치하면, 이 결함이 웹 사이트 스푸핑, 서버 위장, 중간자 공격과 같은 광범위한 보안 공격을 가능하게 만듭니다.

인증서 투명성은 SSL 인증서를 거의 실시간에 가깝게 모니터링하고 감사할 수 있는 오픈 프레임워크를 제공함으로써 이러한 결함을 제거하는데 도움을 줍니다. 특히, 인증서 투명성은 SSL 인증서가 인증서 인증을 잘못 받았거나, 다른 정당하지 않은 곳에서 인증서 인증을 오남용하여 받았는지를 확인할 수 있게 합니다. 인증서 인증이 악의적인 사용자에게 넘어가서 잘못된 인증을 받았는지도 알 수 있게 합니다.

오픈된 공개 프레임워크이므로, 누구든지 인증서 투명성을 구동하는 기본 구성요소를 빌드하거나 접근할 수 있습니다. 이는 특히 도메인 소유자, 인증서 인증자, 그리고 브라우저 제조사와 같이, SSL 인증 시스템의 무결성과 상태를 유지하는 인터넷을 구성하는 인터넷 보안 관계자에게 유용합니다.

인증서 투명성을 더 알아보려면, 도입 문서를 읽어보세요. 이미 인증서 투명성의 기본 개념에 친숙하고, 상세 구현을 알아보려면 상세한 디자인 문서를 확인해보세요. 인증서 투명성 프레임워크를 구동하는 핵심 구성 요소를 빌드하는 방법에 대한 오픈 소스 프로젝트도 있습니다.

인증서 투명성이란 무엇입니까?

현대 암호화 기술 덕택에, 브라우저는 평소에 위조되었거나 가짜 SSL 인증서가 제공되는 수상한 웹 사이트를 판별할 수 있습니다. 그러나, 현재 암호화 기술은 잘못 발급된 인증서나, 위험해졌거나 악의적인 집단에 넘어간 인증 기관(CA)의 인증서가 제공되는 수상한 웹 사이트를 판별할 만큼 뛰어나진 않습니다. 이러한 경우, 브라우저는 인증서에 이상이 없다고 표시하게 되는데, 이에 따라 인증 기관이 멀쩡해 보이고, 방문하고 있는 웹사이트가 인증되었고 연결이 안전하다는 인상을 줍니다.

여기서 문제는, 현재로선 쉽고 효과적으로 SSL 인증서를 실시간으로 감사하거나 감시할 수 없어서, 이러한 오작동이 일어나게 되는 것이고 (수상한 경우 등), 의심스러운 인증서는 보통 탐지되지 않고 인증 철회는 수 주나 몇 개월 후에나 이뤄진다는 것입니다. 게다가, 이러한 종류의 SSL 오작동의 빈도가 더욱 늘어나고 있습니다. 지난 몇 년간 잘못 발급된 수많은 인증서가 합법적인 사이트를 가장하는데 쓰이고, 일부의 경우에는 수상한 소프트웨어를 설치하거나 무고한 사용자에게 침투하는데도 쓰였습니다.

한 가지 사례로, 저명한 네덜란드 인증 기관(DigiNotar)이 공격받았고, 해커는 CA 시스템을 사용하여 가짜 SSL 인증서를 발급할 수 있었습니다. 인증서는 이란에서 Gmail과 Facebook과 같은 수많은 사이트를 가장하는데 활용되었고, 이는 가짜 사이트 소유자가 무고한 사용자에게 침투할 수 있게 했습니다. 다른 사례는 말레이시아 소속의 인증서 기관(DigiCert Sdn. Bhd.)이 실수로 22개의 취약한 SSL 인증서를 발급하여, 웹 사이트를 가장하고 수상한 소프트웨어를 서명하는데 쓰였습니다. 그 결과, 주요 브라우저는 DigiCert Sdn. Bhd.가 발급한 모든 인증서에 대한 신뢰를 철회하였습니다.1

최근에, 거대한 U.S. 소재 인증 기관 (TrustWave)이 고객의 인증서 하나에 대한 하위 루트 인증서를 발급하여 고객이 내부 네트워크 트래픽을 관찰할 수 있게 했습니다. 하위 루트 인증서는 인터넷의 거의 모든 도메인에 대한 SSL 인증서를 발급할 수 있게 합니다. 비록 Trustwave는 인증서를 철회했고 고객에게 하위 루트 인증서를 더이상 발급하지 않지만, 인증 기관의 잘못에 의해 얼마나 커다란 결과를 낳게 되는지를 보여주는 사례입니다.

많은 경우에 잘못 발급된 인증서는 해커에 의해 심각한 결과를 초래할 수 있는 악의적인 공격을 하는데 사용되었지만, 일이 터진 후 후폭풍도 거대하고 위험합니다.

결국, 네덜란드의 인증 기관 인증서는 인증 철회되고, 인증 기관은 폐쇄되었습니다. 인증 철회 및 폐쇄는 네덜란드 사람들이 인증 기관의 SSL 인증서를 발급받은 정부와 개인 사이트를 접속하지 못하게 되는 여파를 만들었습니다.

사태 해결을 위한 인증서 투명성

인증서 투명성은 SSL 인증서 발급 유무를 도메인 소유자, 인증 기관과 도메인 유저에 의해 정밀하게 조사할 수 있도록 개방할 수 있도록 하여 이들 인증서 기반 위협을 대처하는 걸 목표로 합니다. 특히, 인증서 투명성은 세 가지 주요 목표가 있습니다.

  • SSL 인증서를 도메인 소유자를 드러내지 않고서는 인증 기관이 도메인 SSL 인증서를 발급하지 못하게 하거나, 어렵게 만듭니다.
  • 아무 도메인 소유자나 인증 기관이 인증서가 실수 또는 악의적으로 발급되었는지 여부에 대한 공개 감사 및 감시 시스템을 제공합니다.
  • 사용자가 가능한한 실수 또는 악의적으로 발급된 인증서에 속지 않도록 만듭니다.

인증서 투명성은 TLS/SSL 인증 시스템 감시와 특정 TLS/SSL 인증서 감사를 위한 공개 프레임워크를 만듦으로써 이러한 목표를 만족시킵니다. 이 공개 프레임워크는 아래 세 가지 주요 구성 요소로 구성되어 있습니다.

인증서 로그

인증서 로그는 암호로 보호되며, 공개적으로 감사되며, 인증서에 대한 레코드 추가만 가능한, 단순한 네트워크 서비스입니다. 누구든지 로그에 인증서를 등록할 수 있지만, 인증 기관이 최우선 등록자가 될 것입니다. 비슷하게, 누구든지 로그된 특정 인증서가 잘 로그되고 있는지, 그리고 인증서를 검증하기 위해서 암호 증명에 대한 로그를 조회할 수 있습니다. 로그 서버 개수는 많을 필요가 없고 (이를테면, 전세계에 1000개보다 적습니다), 각각은 인증 기관, 인터넷 제공 업체 또는 어떤 다른 조직에서든지 독립적으로 운영될 수 있습니다.

감시자 (Monitors)

감시자는 주기적으로 모든 로그 서버와 접촉하면서 수상한 인증서에 대한 주시를 공개적으로 실행하는 서버입니다. 예를 들어, 감시자는 인증 기관을 잃었거나 인증되지 않은 인증서가 도메인에게 발급되었는지, 비정상적인 인증서 확장이나 인증 기관이 갖고 있는 인증 권한 같은 이상한 권한을 갖고 있는지 알려줄 수 있습니다.

감시자는 대출이나 신용 카드에 여러분 이름으로 누군가 사용할 때 알려주는 것과 같은 신용 경고 알림과 매우 유사한 방식으로 동작합니다. 일부 감시자는 Google 또는 은행, 정부와 같은 회사와 조직에 의해 운영됩니다. 그 외에도 도메인 소유자나 인증 기관이 구매할 수 있는 구독 서비스를 운영할 것입니다. 기술에 정통한 개인도 스스로 감시자를 운영할 수 있습니다.

감사자 (Auditors)

감사자들은 크게 보아 두 가지 기능을 수행하는 가벼운 소프트웨어 구성 요소입니다. 첫째는 로그가 올바르게 쓰이고 있고 암호화가 유지되고 있는지 검증할 수 있습니다. 로그가 제대로 작성되지 않으면, 로그 스스로 이에 대해 서술해야 하고 그렇지 않으면 종료될 수 있습니다. 둘째로 특정 인증서가 로그에 나타나는지를 검증할 수 있습니다. 이는 감사 기능에서 특히 중요한데, 인증서 투명성 프레임워크는 모든 SSL 인증서가 로그에 등록되어 있을 것을 필요로 하기 때문입니다. 인증서가 로그에 등록되어 있지 않다면, 인증서가 수상하다는 의미이며, TLS 클라이언트는 수상한 인증서에 대한 연결을 거절할 것입니다.

감사자는 브라우저의 TLS 클라이언트, 단독 서비스, 아니면 감시자의 보조 기능으로서 필수 구성 요소가 될 수 있습니다. 누구든지 감사자를 만들 수 있는데, 이는 인증 기관이 모든 인증 기관에 대한 운영 투명도를 높일 수 있는 효과적인 방법이므로 인증 기관이 수많은 감사자를 운영할 것입니다.

아울러서, 이들 구성 요소가 실시간으로 새로운 또는 기존에 존재하는 SSL 인증서를 누구든지 관찰하고 검증할 수 있게 하는 공개 프레임워크를 구성합니다.2

오작동의 감소, 안전한 브라우징

이것이 구현되면, 인증서 투명성은 잘못 발급된 인증서, 악의적으로 취득한 인증서, 공격받은 인증 기관과 같은 인증서 기반 공격의 몇 종류에 대한 대비를 하는데 도움을 줍니다. 이 공격은 도메인 소유자의 금전적 손실 증가, 인증 기관의 신뢰 하락 그리고 인터넷 사용자를 웹 사이트 스푸핑, 서버 위장, 중간자 공격과 같은 광범위 공격으로 노출할 수 있습니다.

인증서 투명성 프레임워크는 공개 조사 제공 및 SSL 인증 시스템 개방을 통해 이들 인증서 기반 위협을 격리시키는 것을 목표로 합니다. 비록 공개 프레임워크가 공개적으로 감시자와 감사자에 의해 구통되지만, 인증성 투명성은 현행 SSL 인증 시스템에 빠져있는 몇몇 이점을 제공합니다.

잘못 발급된 인증서, 수상한 인증서, 공격 받은 인증 기관의 조기 탐지

대부분의 경우, 인증서 투명성 시스템은 수상한 인증서나 인증 기관을 수 일, 수 주, 수 개월을 수 시간으로 단축하여 탐지할 수 있습니다.

수상한 인증서나 인증 기관이 감지되었을 때 빠른 이탈

인증서 투명성이 위험한 인증서와 인증 기관을 다루는 기존의 해결 방식에 의존하긴 하지만(예를 들어 인증서 철회), 단축된 탐지 시간은 위험한 인증서나 인증 기관이 발견되었을 때 전체 해결 과정을 가속할 수 있습니다.

전체 TLS/SSL 시스템에 대한 더 나은 확인

인증서 투명성은 새로 발급되거나 존재하는 TLS/SSL 인증서에 대한 공개 감시 및 검증을 지원하는 공개 프레임워크로 설립되었습니다.  이에 (도메인 소유자, 인증 기관, 사용자 같은) 관심 있는 이들에게 TLS/SSL 시스템의 투명도와 상태를 관찰하고 검증할 수 있는 기회를 제공합니다.

집중 솔루션으로서, 인증서 투명성은 HTTPS 연결을 더욱 신뢰할 수 있고 정보 탈취 및 위장으로부터 안전하게 만듦으로써 인증 기관으로부터 개인 서버까지 확장된 신뢰 체인을 강화합니다. 그러나 그 이상으로, 일반적인 보안 관점에서, 인증서 투명성은 광범위한 인터넷 보안 공격을 방어하고, 모든 사용자가 안전하게 브라우징할 수 있도록 도와줍니다.

다음글: 2. 인증서 투명성 작동 방식

OpenSSL을 Ubuntu에서 설치하고 업데이트하는 방법

OpenSSL 을 Ubuntu 16.04에서 설치하고 업데이트하는 방법

OpenSSL은 SSL과 TLS 프로토콜의 오픈 소스 구현입니다. OpenSSL을 Ubuntu 장치에서 설치하고 업데이트하는 것은 무척 간단하며, 이 글은 그에 대한 내용을 다룰 것입니다.

OpenSSL을 설치하고 업데이트하기

OpenSSL의 설치를 시작하기 전에, 현재 버전의 OpenSSL을 다음 명령어로 가져옵니다.

$ openssl version
OpenSSL 1.1.0h  27 Mar 2018

그 후, OpenSSL의 최신 버전을 다음 명령어로 다운로드 받습니다. 좌측 링크를 눌러 다운로드 항목 중에 적절한 버전을 선택합니다. openssl-1.x 형식으로 된 것 중에 최신을 권장하지만, pre가 붙은 버전은 정식 출시 버전이 아니므로 문제가 생길 우려가 있습니다.

버전이 낮은데도 지속적으로 갱신되는 버전이 있는데, 이는 LTS 버전으로, 앞으로 업데이트를 자주하지 않고 최신 기능이 필요하지 않으면서 안정적으로 쓰고 싶은 사람에게 적절합니다.

원하는 항목을 브라우저에서 링크만 복사하여 아래 wget 명령 우측에 채워줍니다. 여기서는 openssl 1.1.1 pre7 버전을 설치하는 모습입니다.

$ cd /usr/src
$ wget https://www.openssl.org/source/openssl-1.1.1-pre7.tar.gz
--2018-06-19 08:49:17--  https://www.openssl.org/source/openssl-1.1.1-pre7.tar.gz
Resolving www.openssl.org (www.openssl.org)... 202.43.57.191, 2600:140b:5000:1af::c1e, 2600:140b:5000:1ab::c1e, ...
Connecting to www.openssl.org (www.openssl.org)|202.43.57.191|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8308876 (7.9M) [application/x-gzip]
Saving to: ‘openssl-1.1.1-pre7.tar.gz’

openssl-1.1.1-pre7.tar.gz   100%[=================================================>]   7.92M  4.00MB/s    in 2.0s

2018-06-19 08:49:26 (4.00 MB/s) - ‘openssl-1.1.1-pre7.tar.gz’ saved [8308876/8308876]

다운로드가 완료되면, 다운 받은 압축 파일을 다음과 같이 풀어줍니다.

$ tar -zxf openssl-1.1.1-pre7.tar.gz

수동으로 컴파일하기 위한 준비 작업이 필요합니다. 다음 명령으로 빌드 도구를 설치해주세요. 아래 명령에 파일을 찾을 수 없다는 오류가 발생하면, 우선 우분투 패키지 업데이트부터 실시합니다.1

$ sudo apt install build-essential

이어서 OpenSSL 컴파일 후 설치 및 업그레이드를 하기 위해서 다음 명령을 사용합니다. cd 명령어 뒤에 디렉토리명은 정확해도 되지만, 여기서는 편의를 위해 와일드카드로 간편하게 들어갔습니다. 둘 이상 존재한다면, 정확한 디렉토리명을 지정해주세요.

$ cd openssl*
$ ./config

참고로 위 ./config 대신 ./Configure --help를 참고하여 원하는 옵션을 더 넣을 수 있습니다. 특정 Cipher는 기본적으로 빠져있어서 이런 작업을 미리 해둬야 설치 후 사용 가능한 경우도 있습니다. 보통의 경우 위 명령으로 충분합니다.

이 작업이 끝나면, make 명령으로 OpenSSL의 설치를 준비합시다.

$ make

컴파일이 다 끝나면, make test 명령을 쳐줍니다.

$ make test

다양한 평가 항목이 완료되면, 루트 권한을 갖고 install을 시작합니다.

$ sudo make install

에러에 대한 언급이 없다면, 성공적으로 설치된 것입니다.

아래는 오류 발생시 따라합니다.

여기서부터 링크를 잘 걸어야 잘 실행할 수 있습니다. openssl 명령 실행시 error while loading shared libraries: libcrypto.so.1.1 등의 오류가 발생할 수 있습니다. libssl.so 또한 마찬가지입니다. 이 때 libcrypto.so와 libssl.so를 /usr/lib/usr/local/lib에 위치한 파일을 향하게 심볼릭 링크를 만들어야 합니다. 각 경로에 들어가서 파일이 (그것도 링크가 아닌 실행 가능한 파일로서) 실존하는지 확인합니다. 기존에 존재하던 예전 버전의 쓰레기가 있다면 제거합니다.

$ sudo rm /usr/lib/libcrypto.so*
$ sudo rm /usr/lib/libssl.so*
$ sudo ln -s /usr/local/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so
$ sudo ln -s /usr/local/lib/libssl.so.1.1 /usr/lib/libssl.so
$ sudo ln -s /usr/local/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so.1.1
$ sudo ln -s /usr/local/lib/libssl.so.1.1 /usr/lib/libssl.so.1.1

그리고 방금 설치한 openssl이 bin 폴더에 바로 저장될 수도 있지만, 다른 곳에 만들어졌을 수 있습니다. 위 make install에서 bin 파일이 어디 만들어졌는지 확인하고, 원래의 openssl을 치워버리고 링크해야 합니다.

$ sudo mv /usr/bin/openssl /root/
$ sudo ln -s /usr/local/bin/openssl /usr/bin/openssl

간단한 설치와 업데이트 방법이죠? OpenSSL은 기본적인 암호화 기능과 다양한 유틸리티 기능을 제공합니다. https 서비스 연결, ssh 터미널에도 쓰입니다. 또한, 명령줄을 통해 온라인 인증서에서 정보를 검증하고 추출하는데도 쓰일 수 있습니다.

사견으로, 빌드 난이도는 nginx보다도 낮은, 무척 쉬움에 속하며 아무래도 종속성이 낮은 원시 코드에 가까워서 그런 것 같습니다. 그러나 시스템 설치 단계에서 기존 버전과 충돌을 처리하는 방법에서 고민해야하는 부분이 많으므로, 시스템 백업을 사전에 한 후 도전하길 강력하게 권합니다.

[번역] Docker 컨테이너를 Windows Bash에서 구동하기

Linux를 위한 Windows Subsystem(WSL)1이 Microsoft의 Build 컨퍼런스 2016에서 발표되었을 때, Windows 개발자들에게 새로운 도구의 세계가 열렸습니다. 개인적으로, PowerShell, Bash와 예전의 낡은 cmd까지, 스크립트를 할 때 자유롭게 고를 수 있다는 점을 참 좋아합니다. 그리고 Windows Bash에서 Docker 를 구동하지 못하고 있다는 점은 저를 지금까지도 괴롭게 합니다.

이 글의 원본 제목은 “Windows Bash에서 Docker를 구동하기”였습니다만, 이는 다소 과장되어 있습니다. Docker 는 Windows에서 완전히 완성되지 않은 수많은 시스템 호출에 대한 접근을 필요로 하며, 이로 인해 WSL에서 엔진을 구동하는 것은 아마도 쉽지 않을 것입니다. 대신, 우리는 Docker Engine을 Windows에서 구동하고 이를 Bash에서 연결할 것입니다. 이 또한 PowerShell에서 컨테이너를 시작하고 Bash로 상호작용하거나, 다른 방식을 제공한다는 장점을 갖고 있습니다. 다시 말해서, 당신의 컴퓨터가 단일 머신처럼 느껴질 것입니다.

그 방법을 알아봅시다.

1. Docker를 Windows에서 설치하기

Docker 엔진을 Windows에서 설치하려면, docker.com에 가서 적절한 배포판을 다운로드합니다. 물론, 하드웨어 가상화가 활성화돼있고, Hyper-V가 설치되어 있어야 하며, 그렇지 않으면 엔진이 시작되지 않습니다.

가장 빠른 방법: Windows 10 크리에티터 업데이트 설치

Windows 실행 파일을 Bash에서 실행할 수 있게 되었기 때문에, Windows 10 크리에이터 업데이트에서는 이 과정이 더욱 단순해졌습니다. 그저 아래 두 줄을 .bashsrc에 추가하고 (환경을 다시 로드하면) 끝납니다!

export PATH="$HOME/bin:$HOME/.local/bin:$PATH"
export PATH="$PATH:/mnt/c/Program\ Files/Docker/Docker/resources/bin"
alias docker=docker.exe
alias docker-compose=docker-compose.exe

docker –version을 Bash에서 실행하면, 나머지 글을 읽을 필요도 없습니다. :)

*) Windows 10 크리에이터 업데이트는 2017년 4월 11일에 인사이더에 공개되었으며 현재 유효합니다.

Windows 10 애니버서리 에디션에서 작동하는 법

Docker를 WSL에 설치하기 위해서, 몇 가지 더 많은 단계가 필요합니다. 일부 선택적 단계를 제외하고는 WSL에서도 잘 작동하는, 일반적인 Ubuntu 설치 방법은 여기 적혀 있습니다.

제가 한 방식은 이것입니다:

# Install packages to allow apt to use a repository over HTTPS
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# Add Docker's official GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Set up the repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Update source lists
sudo apt-get update
# Install Docker
sudo apt-get install docker-ce

물론 필요한 바이너리를 다운받고 압축을 푸는 작업, 그리고 그것을 PATH에 넣는 방식의 선택지도 있습니다. 가장 최신 버전에 맞는 방법은 여기 적혀 있습니다.

그 결과는?

Docker 엔진을 Windows와 WSL 양쪽에 설치했지만, 둘 다 구동하진 않았습니다. Windows 인스톨러는 고맙게도 Docker 엔진을 시작할 때 쓰는 Docker 바로 가기를 바탕 화면에 만들어놨습니다. 그리고 docker images를 PowerShell이나 Bash에서 호출할 수 있습니다.

PowerShell:

PS C:\> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

아직까지 이미지를 아무 것도 만들지 않았지만, 괜찮습니다.

Bash:

$ docker images
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

전혀 만족스럽지 못하군요. 하지만 한 두 가지 과정을 더 거치면, 모두 잘 작동할 것입니다.

2. Windows Docker로 WSL의 Docker 연결하기

docker를 다른 장치의 엔진을 대상으로 구동하는 것은 꽤 쉬운데, Docker가 CLI가 연결될 수 있는 TCP 엔드포인트를 노출할 수 있기 때문입니다.

참고: 글을 처음 공개한지 얼마 되지 않아서 Docker 업데이트를 통해 이 TCP 엔드포인트는 기본적으로 꺼져 있습니다. (Mark님 알려주셔서 감사해요!) 활성화하려면, 작업표시줄에 있는 Docker 아이콘을 우클릭하여, 메뉴에서 설정을 들어갑니다. 그리고 “Expose daemon on tcp://localhost:2375 without TLS” 옵션을 켭니다 (보안 위험성에 유의합니다).

export PATH="$HOME/bin:$HOME/.local/bin:$PATH"
export PATH="$PATH:/mnt/c/Program\ Files/Docker/Docker/resources/bin"
alias docker=docker.exe
alias docker-compose=docker-compose.exe

이렇게 하면, 다음처럼 할 일은 Bash 상의 CLI가 Bash 상에는 없는 엔진 대신에 Windows에서 엔진을 실행하게 됩니다.

$ docker -H tcp://0.0.0.0:2375 images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

훨씬 낫군요!

이 상태를 지속하게 만드는 두 가지 방법이 있습니다. 위 명령을 별명으로 추가하거나, 아니면 더 나은 방법으로(Dave님의 추천), Docker가 호스트 엔진을 찾도록 환경 변수를 만들면 됩니다.

$ echo "export DOCKER_HOST='tcp://0.0.0.0:2375'" >> ~/.bashrc
$ source ~/.bashrc

이제, 도커 명령을 Bash에서 실행하면, 우리가 바라던 대로 작동하게 됩니다.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

미션 성공!


이 글에서 사용한 버전

물론, 이 방법이 사용하는 버전에 따라 되지 않을 수 있습니다. 이 블로그 포스트에서는 다음과 같은 버전을 사용하였습니다.

Windows

Windows 10 Pro Anniversary Edition (Version 1607, OS Build 14393.1066)
Windows 10 Pro Creators Update (Version 1703, OS Build 15063.138)

WSL Ubuntu

14.04.5 LTS

Docker on Windows

17.03.1-ce, build c6d412e

Docker on Ubuntu

17.03.1-ce, build c6d412e

출처: https://blog.jayway.com/2017/04/19/running-docker-on-bash-on-windows/

제로부터 시작하는 Git(형상관리툴) 라이프 1

Git을 써야 하는 이유

형상관리 버전 관리에서 가장 우수하다고 여겨지는 것은 Git이라 할 수 있을 것이다. Git은 다음과 같은 특징이 장점으로 꼽히고 있다.

  1. 파일 단위로 변경 내용을 추적하며, 스테이지 후 커밋-푸시 과정을 거치며 파일 단위로 업로드할 수 있다.
  2. 중앙 서버 중심이 아니다. 분산 저장을 한다.
    • Git은 분명 원격 서버를 갖고 있지만, 서버와 연결되어 있지 않더라도 로컬 커밋까지는 무난하게 할 수 있다. SVN은 원격 서버 연결을 잃으면 일체의 커밋을 할 수 없다.
    • 로컬에 쌓인 커밋을 추후에 푸시하면, 서버와 동기화가 이뤄진다.
  3. 거의 대부분의 경우 충돌을 유연하게 해결할 수 있다.
  4. 소스 보관 및 복제용으로 활용할 수 있다.
    • Github가 git을 활용한 대표적인 공개 서비스로, 여기에 Public으로 올리면 무료로 소스 코드를 공개한 것이며, 누구든지 clone할 수 있다.
    • Git을 Clone하면 저장소의 역사와 내용이 통째로 복사되어 서버 유무와 무관하게 재업로드하여 역사를 이어갈 수 있다.
  5. 커밋이 용량을 크게 더욱 차지하지 않으며, 언제든지 되돌리거나 다른 커밋을 체크아웃할 수 있다.
    • Branch를 분기하여 사람들마다, 혹은 기능마다 나눠서 준비된 것만을 Merge하면 만들다가 만 기능탓에 컴파일을 할 수 없는 불편한 일이 사라진다.
    • 새로운 기능이 문제를 일으키는 것 같으면, 과거의 커밋을 꺼내올 수 있고, 다른 Branch로 갈아탈 수 있다.
    • Checkout을 하면, 로컬의 파일이 모두 변경되는데 그렇다고 커밋했던 기존의 파일이 사라지는 것 또한 아니다. 프로젝트 폴더 내용을 임시폴더처럼 부담없이 변경할 수 있다.

한편, 형상관리 버전 관리를 경험해보지 않은 사람은 “구글 드라이브나 카카오톡으로 압축하여 공유하면 되지”라고 생각하기 쉽다. 이는 다음과 같은 이유로 피해야 한다.

  1. 같은 파일이 다수 난립하여 선후 관계가 혼란스럽다.
    (최종.zip, 최종.zip (1), 최종-진짜.zip이 쌓여간다고 상상해보자. 극혐)
  2. 프로젝트 파일 전체를 압축하고 복사(업로드/다운로드), 해제하는 불필요한 과정으로 시간 낭비과 수고가 심하다.
  3. 매 순간 무엇을 변경하였는지 불투명하다.
  4. 이전에 되던 기능이 망가진 경우, 그 원인을 찾기란 무척 어렵다.
  5. 누군가 안 된다고 호소할 때, 그 사람의 파일이 최신으로 모든 파일 내용이 일치하는지 알 길이 없다.

Git을 쓰기 위한 준비

Windows 환경에서 Git을 쓰기 위해서는 크게 두 가지 유의할 점이 있다.

  • 클라이언트에서의 고민
    • Git을 명령어로 쓰겠는가?
      • Git 바이너리는 분명 명령 프롬프트나 bash 등에서 작동하는 CLI 앱으로, 사용하기에 불편하지만, GUI에 없는 기능을 쓰기 위해서 꼭 존재해야 한다.
      • 일부 GUI Git은 별도로 바이너리를 넣어줄 필요가 있지만, 대체로 GUI만 쓰는 경우 Git 또한 설치할 필요는 없다. 하지만 위 이유로 둘 다 깔면 좋다.
    • Git을 편하게 쓸 GUI를 선택하자.
      • SourceTree가 한글화 지원과 깔끔한 환경으로 널리 쓰이고 있다. 그러나 기능면에서 아쉬운 점이 있다.
      • GitKraken은 본 글에서 소개할 앱으로, 풍부한 기능과 막강한 시각화를 보여주고 있다. 그러나 영문만을 지원하고 있다.
      • TortoiseGit은 탐색기와 결합이 뛰어나나 기능이 많지 않고 직관적이지 못하다.
      • eclipse의 eGit, Visual Studio의 git 등 내부 소스 관리 플러그인을 활용할 수 있다. 하지만 최소한의 기능만을 제공하며 UI도 직관적이지 못해서 git에 대한 오해를 키울 수 있으며, 충돌 등 문제 해결이 어렵거나 불가능한 경우가 있다. 매우 비추천한다.
  • 서버에서의 고민
    • 누구든지 git 바이너리를 이용하여 git server를 셋팅할 수 있다.
    • github와 bitbucket과 같은 웹 git을 이용할 수 있다.
      • github: Public의 경우 무료. Private는 팀원당 7달러 비용
      • bitbucket: Public 무료. Private도 5명 이내인 경우에는 무료.
    • Synology NAS에 git을 깔아 쓰면 SSH 프로토콜로 접속하여 사용할 수 있다.

Git for Windows 다운로드

Linux 환경에서는 기본적으로 깔려있는 경우가 많고(Ubuntu 등), 필요시에도 단순한 명령으로 설치할 수 있다.

Linux Git 다운로드 페이지

Git을 컴퓨터에서 설정하려면

GUI만 쓴다면 필수 사항은 아니지만 git 커맨드 라인의 사전 설정을 해둘 필요가 있다.

우선 위 링크에서 파일 다운로드를 모두 마치고 설치한다. PATH 설정이 적용되기 위해서는 켜져 있는 명령 프롬프트를 모두 종료한 다음 다시 켜고, 필요한 경우 시스템 재시작도 도움이 된다.

다음과 같은 메시지를 보았다면, 경로가 제대로 등록되지 않은 것이다.

> git
'git' is not recognized as an internal or external command,
operable program or batch file.

이렇게 뜨면 성공한 것이다.

> git
usage: git [--version] [--help] [-C ] [-c name=value]
           [--exec-path[=]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=] [--work-tree=] [--namespace=]
            []

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Reapply commits on top of another base tip
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help ' or 'git help '
to read about a specific subcommand or concept.

이제 기본 사용자 설정을 해보자. 아래 명령 한 번만 내려주면 커맨드 라인에서 git commit시 항상 먼저 설정된다.

> git config --global user.name "My Name"
> git config --global user.email [email protected]

한 번 쓰면 계속 쓰게 되는 GitKraken

나머지 기능은 이어서 적어보도록 하겠습니다.

SCIT Schedule Hi

SCIT Schedule Hi (2018)

SCIT Schedule Hi
SCIT Schedule Hi

SCIT Schedule Hi는 SCIT Master 재학생이 편하게 자신의 지원 기업과 관련된 일정을 확인하고, 변동 사항을 알림으로 전달받을 수 있는 프로그램입니다.

개발 동기

SCIT 면접 시즌이 되자 학생들의 생활은 무척 불안해졌습니다. 불안한 마음을 안고 시설내 사이트에서 F5를 연타하면서 캘린더를 확인하는 모습은 전혀 자기 개발적이지 못하다는 생각이 쌓여갔습니다. 접속하지 않고도, 앱을 켜는 것, 아니 컴퓨터를 켜는 것만으로 자신의 새로운 일정을 확인할 수 있다면 훨씬 편할 것이라는 생각을 하게 되었습니다. 그러면 GET 1회와 POST 1회 도합 2회 요청이 단 1회로 줄어들고, 더 짧은 기간에 갱신도 가능하게 됩니다. 폴링도 훨씬 가볍고, 시설 입장에서도 트래픽을 절감할 수 있겠지요.

개발 언어 및 도구

  • Language: C#
  • Tool: Visual Studio 2017
  • Template: WPF Application

“SCIT Schedule Hi (2018)” 더보기

알고리즘 탐구 – 인접한 원소의 위치 구하기

문제

U < V < W 또는 U > V > W일 때, 정수 V는 U와 W 사이에 있다.

비어 있지 않은 배열 A는 주어진 N개의 정수로 이뤄져 있는데, 숫자의 인덱스 (P, Q) 짝은 0 ≤ P < Q < N인 인접한 수가 A[P]와 A[Q] 사이에 없으며, A[P]≠A[Q]임을 나타낸다.

예를 들어, 배열 A에서는:

A[0] = 0
A[1] = 3
A[2] = 3
A[3] = 7
A[4] = 5
A[5] = 3
A[6] = 11
A[7] = 1

다음 인덱스 짝은 인접한 값을 갖고 있다.

(0,7), (1,4), (1,7), (2,4), (2,7), (3,4), (3,6), (4,5), (5,7)

예를 들어, 인덱스 4와 5는 인접한 값을 갖고 있는데, 왜냐하면 A[4] = 5와 A[5] = 3는 다르며, 배열 A에는 그 사이에 들어갈 값이 없다는 것이다. 즉, 숫자 4만이 사이에 들어갈 수 있으나 배열에 존재하지 않는다.

주어진 두 인덱스 P와 Q의 거리는 X ≥ 0에서는 abs(X) = X, X < 0에서는 abs(X) = -X일 때  abs(P-Q)로 정의된다. 예를 들어, 인덱스 4와 5 사이 거리는 1인데, 그 이유는 abs(4-5) = (5-4) = 1이기 때문이다.

함수를 작성하라:

class Solution { public int solution{int[] A); }

주어진 비어 있지 않은 배열 A는 N개의 정수로 이루어져 있으며, 인접한 값을 가진 배열의 가장 긴 거리를 반환한다. 이 함수는 인접한 인덱스가 없는 경우 -1을 반환해야 한다.

예를 들어, 주어진 배열 A는 다음과 같다:

A[0] = 1
A[1] = 4
A[2] = 7
A[3] = 3
A[4] = 3
A[5] = 5

이 함수는 다음 이유로 4를 반환해야 한다:

  • 인덱스 0과 4는 인접해있는데, 그 이유는 A[0] ≠ A[4]이며 배열이 A[0] = 1과 A[4] = 3 사이의 값을 갖고 있지 않기 때문이다.
  • 이들 인덱스의 거리는 abs(0-4) = 4이다.
  • 더 큰 수의 거리를 지닌 다른 인접한 인덱스 짝이 없다.

다음과 같이 가정한다:

  • N은 [1..40,000] 범위 내에 있다.
  • 배열 A의 각 요소는 정수이며, 범위 [-2,147,483,648..2,147,483,647] 내에 있다.

복잡도:

  • 기대되는 최악의 경우 시간 복잡도는 O(N*log(N))이다.
  • 기대되는 최악의 공간 복잡도는 O(N)이며 입력 공간 이후를 말한다 (입력 기호에 필요한 공간은 포함하지 않는다)

발상

  • 왼쪽부터 찾아서 그 값의 다음 인접한 수를 찾는 식으로 반복할까?
    • N개의 항목에 대해 반복하면서 N-1개의 반복을 다시 해야만 한다.
    • 더 좋은 방법이 있을 것이다.
  • 소트를 먼저 한 다음에 낮은 수부터 올라가면서 맞춰볼까?
    • 소트 알고리즘은 검증되어 있는 내부 라이브러리를 활용하면 더 좋을 것이다.
    • 같은 수를 건너뛰면 반복문이 한층 더 빠를 것이다.
    • 하지만 정렬하면 원래의 위치를 잃어버리잖아?
      • 원래의 위치는 왼쪽부터 차례로 원시적인 방법으로 찾으면 된다.
      • 찾는 순간 루프를 탈출하면 속도는 더욱 빠를 것이다.

풀이

import java.util.ArrayList;
import java.util.Arrays;

public class Question {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//int[] A = new int[] {0,3,3,7,5,3,11,1};
		//int[] A = new int[] {1,4,7,3,3,5};
		//int[] A = new int[] {1,1,1,1,1,1,1,1};
		
		//랜덤한 40000개의 int를 넣는 부분
		int[] A = new int[40000];
		for(int i = 0; i < A.length; i++) {
			A[i]=(int)Math.round(Math.random()*2147483647*2-2147483647);
		}
		
		//시간 계산 시작
		long startTime = System.nanoTime();
		System.out.println("Result: "+solution(A));
		System.out.println("Elapsed Time: "+(System.nanoTime()-startTime)/1000000.0+"ms");
	}
	
	private static int indexOfArray(int[] A, int val, boolean reverse) {
		if(reverse) {
			//뒤에서 찾기
			for(int i = A.length-1; i >= 0; i--) {
				if(A[i]==val) {
					return i;
				}
			}
		} else {
			//앞에서 찾기
			for(int i = 0; i < A.length; i++) {
				if(A[i]==val) {
					return i;
				}
			}
		}
		return -1;
	}
	
	private static int findPairDistance(int[] A, int min, int max) {
		//왼쪽 오른쪽 각각 min, max 검색
		int aleft = indexOfArray(A,min,false);
		int aright = indexOfArray(A,min,true);
		int bleft = indexOfArray(A,max,false);
		int bright = indexOfArray(A,max,true);
		return Math.max(Math.abs(aleft-bright),Math.abs(aright-bleft));
	}
	
	public static int solution(int[] A) {
		//소트 후 중복 제거
		int[] sorted = A.clone();
		Arrays.sort(sorted);
		/*for(int i = 0; i < sorted.length; i++) {
			System.out.print(sorted[i]+",");
		}*/
		//ArrayList alSel = new ArrayList<>();
		int max = -1;
		for(int i = 1;i < sorted.length; i++) {
			//전항과 현재항의 차이
			int cha = sorted[i]-sorted[i-1];
			if(cha >= 1) { //차이가 1 이상이면 정수 변화로 보고 계산
				//alSel.add(sorted[i-1]);
				//findPairDistance(A,A[i-1],A[i]);
				max = Math.max(max, findPairDistance(A,sorted[i-1],sorted[i]));
				//두 값에 대한 좌우 검색 최대 거리를 구한 다음 max보다 클 때만 기록
				//System.out.println(String.format("값: (%d,%d), 거리: %d",sorted[i-1],sorted[i],findPairDistance(A,sorted[i-1],sorted[i])));
			}
		}
		
		
		return max;
	}

}

IIS에서 cipher 보안 개선하여 SSLLabs 고득점 노리기

IIS 의 SSL은 안전하지 않다?

Windows 10 1607, 그것도 Server 2016 1607이라는 나름대로 최신1 버전을 사용중이면서 IIS 를 지난 게시물에서 세팅한 바 있습니다. 그러나 그런 과정을 거쳐서 Let’s encrypt를 설정했는데도 불구하고 뭐가 부족했는지 SSLLabs에서는 가차없는 점수를 주었네요. 무엇이 문제일까요?

RC4를 써서는 안 되는 이유

RC4 암호화는 1987년 설계된 스트림 암호입니다. 스트림 암호인 만큼 빠르게 적용할 수 있고, 그간 널리 쓰여온 바가 있지만 이제는 사용을 권하지 않는다고 합니다. 다양한 취약점이 발견되었으며, 암호의 복잡도가 충분히 높지 않아서 무력화되기 쉬우며, 이 취약점이 바로 무선랜 암호화인 WEP를 신용할 수 없게 하는 주요 원인이기도 합니다. 그래서 새로운 SSL 프로토콜에서는 도입되지도 않았으며, 그런 낡은 것을 IIS 는 여전히 지원한다는 점에서 HTTPS 보안에 대한 점수를 크게 감점하게 된 것입니다.

Cipher 선택에 따라 좌우되는 보안

SSL에 대한 그간의 글에서 언급하였던 보안 사이퍼(cipher)는 암호화 방법을 의미합니다. 서버가 암호화할 줄 알아야 하겠지만, 클라이언트도 복호화할 줄 알아야만 올바르게 정보를 전달할 수 있을 것입니다. Cipher는 암호화 알고리즘으로 정의되며, 그 종류는 무척 다양합니다. 개중에는 최신식 고급 보안을 가진 것도 있는가 하면, 옛날부터 쓰던 것이라 취약점이 알려질대로 알려진 낡은 것도 있습니다.

물론 가장 최신의 알고리즘을 쓰면 더욱 안전한 건 당연하겠지만, 모든 브라우저를 만족시킬 수 없기 때문에, 옛날 OS에서는 에러 메시지만을 보게 될 것입니다. 그런 점을 고려하여 호환성과 안전 두 가지의 균형점을 갖춰보고자 합니다. 즉, 이 글은 조금 더 실용적으로 포장된 기존의 글 재탕으로 보셔도 될지 모릅니다.

IIS 에서 Cipher 선택하기

[시작]→[실행]을 들어가서 ‘gpedit.msc’를 실행하면 그룹 정책이 뜹니다. 그룹 정책에서 다음 경로로 들어갑니다.

컴퓨터 관리\관리 템플릿\네트워크\SSL 구성 설정

SSL Cipher Suite Order 항목을 눌러서 ‘사용’을 누르면 아래 입력칸이 한 줄로 있습니다. 한 번 기본값 전체를 살펴보겠습니다.

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5,
TLS_RSA_WITH_NULL_SHA256,
TLS_RSA_WITH_NULL_SHA,
TLS_PSK_WITH_AES_256_GCM_SHA384,
TLS_PSK_WITH_AES_128_GCM_SHA256,
TLS_PSK_WITH_AES_256_CBC_SHA384,
TLS_PSK_WITH_AES_128_CBC_SHA256,
TLS_PSK_WITH_NULL_SHA384,
TLS_PSK_WITH_NULL_SHA256

RSA + PSK WITH NULL 있는 거 실화냐 / ECDSA랑 AES 붙을 때 자신감 있는 NULL

후순위이긴 하나 RC4는 물론 별다른 암호화가 없는 것으로 보이는 것도 보입니다. 이것이 보안의 허점을 노출하는 것으로 봐도 무방하겠습니다.

Windows에서 제안하는 변경점

Windows에서도 관련된 정보를 공개하고 있습니다. 여기 서술대로라면, 일단 크게 봐서 두 가지에 주의해야 합니다.

  • 일부 cipher는 HTTP/2 버전 연결을 미지원하므로 통신에 실패합니다. HTTP/1.1보다 HTTP/2가 지원하는 브라우저에선 서버 연결 속도에서도 압도적으로 낫기에 충분히 고려해봐야 합니다.2
  • SCH_USE_STRONG_CRYPTO시 Yes 되어 있는 것은 안전한 것으로 보고 있습니다. 그러나 여기서 Yes여도 SSLLabs의 깐깐한 판단으로는 WEAK에 속할 수 있습니다.

여기서 SCH_USE_STRONG_CRYPTO가 Yes인 것만 골라서 넣어보겠습니다.

TLS_PSK_WITH_AES_256_GCM_SHA384,
TLS_PSK_WITH_AES_128_GCM_SHA256,
TLS_PSK_WITH_AES_256_CBC_SHA384,
TLS_PSK_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256

그리고 다시 SSLLabs 테스트를 받으니 여전히 WEAK 판정은 존재합니다. RC4를 없애니 랭크도 A로 올랐군요.

문제가 된 cipher를 추려내보겠습니다.

TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA

해당 cipher를 제거하고 넣으면 되겠군요. 추가적으로 최신 브라우저의 우선순위에 맞게 순서를 재배열하였습니다.

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_PSK_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_128_GCM_SHA256
TLS_PSK_WITH_AES_256_CBC_SHA384
TLS_PSK_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256

HSTS 설정을 올바르게 하면 점수가 오를 것이다

이제 Cipher를 무결하게 만들고, 마지막 단계로 HSTS 설정을 하여 A+를 노려보겠습니다.

SSL이 강제될 사이트에서 HTTP Response Headers를 들어갑니다.

[Add…]를 눌러서 새로운 항목을 추가합니다.

다음과 같이 Strict-Transport-Security를 지정합니다. 이 값을 지정하고 헤더로 전송되면, 사용자 클라이언트 브라우저에선 향후 이 사이트에 대한 요청을 반드시 HTTPS로만 하게 되며 더욱 안전한 통신이 가능해집니다.

단, 추후 인증서를 해지하거나 만료되면 사이트에 아예 접속할 수 없을 수 있으니 이 설정에 유의하고 인증서가 없어지거나 만료되지 않도록 갱신 및 관리에 항상 신경써야 합니다.

Name: Strict-Transport-Security
Value: max-age=31536000

SSLLabs는 최소한 120일(10368000초) 이상 주어야 한다고 하며, 이상적인 값은 1년(31536000초)라고 합니다.

또한 평문 전송시 이러한 값을 전송해서는 안 되므로, redirect 전용 사이트 하나를 만들고 SSL 전용 사이트로 지정한 메인 사이트에서만 이러한 설정을 하는 것이 좋겠습니다.

저런, A+가 아직 나오지 않았어요

IIS의 한계랄까 안타까운 부분입니다. 이 부분에 대한 대응을 또 하나씩 해봅시다.

  • SHA1과 RC4 등 RC가 Cipher에 없음을 확인했습니다.
  • OCSP Stapling은 기본적으로 IIS가 챙기는 부분으로 별도의 설정은 불필요합니다. 다만, Must Staple 옵션을 적용할 방법이 보이지 않는군요.
  • Forward Secrecy는 ECDHE와 DHE를 지원한다면 저절로 robust support 될 것입니다.
  • TLS_FALLBACK_SCSV: 브라우저가 폴백(차선책) 시도를 할 수 있게 하여 구식 보안으로 다운그레이드하여 보안성을 약화시키는 것을 방지하는 기능입니다. 적절히 처리하지 못하면 POODLE 공격으로 이어질 수 있는데요. 안타깝게도 이 기능은 IIS에서 지원되지 않습니다.
    • 대신 TLS1.2 버전을 단독 지원함으로써 낮은 버전의 보안 연결을 원천적으로 봉쇄할 수 있습니다.
    • TLS1.2만 허용하게 되면서 버려지는 지원 기기의 예시는 다음과 같습니다.
      • Android 4.3 이전의 기기들
      • Baidu 2015년 1월 이전 버전
      • XP의 IE63~IE8
      • Vista의 IE7~IE8
      • Windows 7의 IE8~IE10 (Windows 7 현재 최신은 IE11)
      • Windows Phone 8.0의 IE8
      • Java 6, Java 7
      • OS X 10의 Safari 6.x

이 조치의 결과 A+를 획득하는데 성공했습니다. 그러나 버려지는 기기가 너무 많은 게 흠인 것 같습니다.

HangmanAndroid (2018)

HangmanAndroid는 인터넷에 연결된 상태에서 서버측과 통신하여, 접속한 모든 사람들과 동시에 단어 문제를 풀어 맞추는, 행맨 게임 형식의 안드로이드 앱입니다.

개발 동기

SCIT 마스터 제 3회 개인 프로젝트

BokunoVoca 개발로 단어 학습 프로그램에 대한 가능성과 동시에 아쉬움도 느꼈습니다. 여기서 네트워크 기능을 적극적으로 접목하면 더욱 재미있는 기능을 만들 수 있을 것이라는 기대가 커졌습니다. 특히 Spring과 Android의 조합으로 HTTP 통신으로 구성할 수 있다면, 그 역량은 더욱 커질 것이라 봤습니다. 마침 Wordament라는 기존의 Microsoft Studio 게임이 떠올라서 그런 형식으로 전세계인이 동시에 즐길 수 있는 게임을 한 번 만들어보자는 발상을 하기에 이르렀습니다.

개발 언어 및 도구

  • JAVA, Android
  • Android Studio
  • Android SDK API 23 (Marshmallow)

“HangmanAndroid (2018)” 더보기

Windows Server IIS를 ASP 원격 배포 가능하도록 만들기

Java를 해보신 분이라면 Spring MVC로 Apache Tomcat에 한방에 올라가는 Eclipse의 연동된 환경이 꽤나 매력적으로 느껴지셨을 겁니다. 요즘은 파일 하나하나를 FTP로 업로드하기보단 패키지로 만들어서 설치하듯이 한 덩어리로 사이트를 구축하는 것이 관리하기도 편하고, 문제가 발생할 소지도 적어서 더 널리 쓰이는 게 아닌가 생각이 들 정도입니다.

이 글은 IIS에서 ASP 원격 배포가 가능하도록 설정하는 방법을 제시합니다.

준비물

  • Windows Server 2012 이상의 서버 OS
    • 당연히 IIS 역할이 추가되어 있어야 합니다.
    • Windows 8.0, 8.1 미지원으로 문서에 나와 있는데, Windows 10에서도 관련된 권한 옵션을 제공하는지 확인하지 못했습니다.
  • Web Deploy 설치 파일 (.msi)
  • 개발용 PC의 경우 Visual Studio 2017 Community 이상
    • 패키지를 만들어서 제공할 수 있는 다른 컴퓨터입니다.

순서

서버 역할 추가하기

서버 관리자에서 역할 및 기능 추가를 눌러줍니다.

IIS 관리 도구를 모두 선택해서 설치해줍니다. 이걸 먼저 해줘야 별탈이 없더군요.

Web Deploy 설치하기

Web Deploy 소프트웨어를 설치합니다. Web PI에서 3.5, 3.6 버전을 손쉽게 설치할 수 있습니다만, 이걸로 많은 문제가 발생합니다.

가장 흔한 게 접속 테스트에서 404, 550 같은 문제가 발생한다는 것입니다. 필요한 구성요소가 기본으로 선택되지 않은 채 설치가 진행되기 때문입니다.

그런 염려를 덜기 위해서는 직접 위 준비물 단락에 있는 링크에 들어가서 msi 파일을 다운받아 설치를 진행할 필요가 있습니다.

설치 마법사에서 모든 구성 요소 설치를 필히 선택해주세요. 설치가 완료되면 서버를 한 번 재부팅할 필요가 있습니다.

IIS 메뉴부터가 달라지거든요.

IIS 추가 설정

재부팅은 무사히 하고 오셨습니까? IIS에서 할 일이 좀 더 남았습니다.

모든 것이 순조롭게 설치되었다면, 관리 서비스 위임(Management Servicec Delegation) 항목이 설치되었을 겁니다.

지금은 이 항목에서 할 일은 없습니다.

내가 관리할 사이트를 (만들거나, 기존의 것을) 선택하여 마우스 우클릭으로 메뉴를 펼치고, [배포(Deploy)]→[웹 배포 게시 설정(Configure Web Publish Deploying…)]을 누릅니다.

여기서 게시 권한을 지정하고 설정하면 이 사이트에 대한 배포를 수용할 수 있게 됩니다.

사이트 설정이 완료되면 관리 서비스(Management Service)로 들어갑니다.

ID 자격 증명을 적합하게 설정하고 인증서도 https에서 쓸 수 있도록 올바른 것을 골라줍니다.

자신의 도메인 이름과 일치한 인증서를 사전에 발급받았다면 더욱 편리하게 설정할 수 있겠지요.

접속 테스트

올바르게 설정했으면 Visual Studio에서 접속을 확인해봅니다.

솔루션의 프로젝트 메뉴에서  [게시(Publish)…]로 진입합니다. 이미 게시한 적 있으면 저장된 프로필이 뜹니다.

타겟 방법은 IIS로 합니다.

Web Deploy를 선택하고 서버(IP / 호스트 이름), IIS 메뉴로 보이는 사이트 이름(기본 사이트), 유저명, 비밀번호, 목표 URL을 입력합니다.

목표 URL은 연결에 영향을 주지 않지만 미리보기 주소로 활용되는 듯 합니다.

[연결 테스트 (Vaildate Connection)] 버튼을 누르면, 상기 설정에 문제 없을 경우 통신 성공 여부가 뜹니다.

방화벽 설정

혹시 접속에 실패하는 경우 Windows 방화벽이 방해하고 있을 수 있습니다. 상기 항목이 제대로 옵션이 켜져 있는지 확인해봅시다.

테스트 프로젝트 배포

일반적인 문제 해결 방법

  • Web Deploy를 재설치하거나 업그레이드하는 경우, 관리 명령 프롬프트에서 다음과 같은 명령을 실행하여 핸들러와 에이전트를 다시 실행합시다.
    • net stop msdepsvc & net start msdepsvc
    • net stop wmsvc & net start wmsvc
  • 경로상에 있는 방화벽이 통신을 방해하지 않아야 합니다. Web Deployment Agent Service는 일반적으로 80포트를 쓰며, Web Management Service는 8172 포트를 씁니다.
  • MsDepSvc는 Administrator 또는 도메인의 Admin 그룹에서 실행되어야 합니다. 로컬 계정에서는 정상적으로 작동하지 않습니다.
  • .NET 4.0이 IIS에 등록되지 않았을 수 있습니다.
    • .NET 4.0이 설치되었으나 IIS 서비스 풀에 등록되지 않았을 수 있습니다. 그 원인은 .NET 4.0이 IIS 설치 전에 깔려 있지 않았기 때문입니다.
    • 다음 명령을 실행하여 해결합니다.
      • %systemdrive%\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -iru

결론

Spring 부럽지 않은 일사천리 개발 환경이 갖추어졌습니다. SQL도 한방에 연결할 수 있는 것 같은데 관련된 정보를 더 많이 알아봐야 활용이 편리할 것 같습니다.

IIS 7에서 LetsEncrypt 설정하기

LetsEncrypt 는 무료 인증서 발급으로 https 확산에 혁혁한 공을 세운 단체입니다.1

특히 Certbot이라는 훌륭한 도구 덕분에 Linux 계열에서 Apache를 쓰든 Nginx를 쓰든 상관 없이 명령 몇 줄로 인증받는 시대가 열렸습니다.

그러나 윈도우에서는 공식적으로 LetsEncrypt 설치를 하는 방법이 제공되지 않습니다. 하지만 소스가 충분히 공개되어 있기에 누구든지 LetsEncrypt 인증 서버에 인증을 요청하고 인증서를 발급할 수 있습니다.

그러면 그냥 명령 쳐서 발급받으면 되잖아.

라고 하기엔 LetsEncrypt 인증서의 기간이 90일 이내로 짧기 때문에 자동 실행으로 갱신받아야만 하고, 그런 일을 대신해줄 프로그램은 필수입니다.

그런 역할을 해줄 프로그램을 소개해볼까 합니다.

Certify The Web

https://certifytheweb.com/

현재는 3.0.11 Stable 버전과 4.0의 Alpha 버전으로 나뉘어 있습니다. Alpha4가 문제가 있어서 Alpha3로 재공개했다는군요.

설치는 꽤 빠르게 이루어집니다.

메인 화면은 이렇게 생겼습니다.

바로 New Certificate를 눌러서 새로운 인증서를 발급해봅시다.
참고로 정식 버전이 아닌 경우에 상용으로 쓰지 말라고 경고가 여러 차례 뜹니다.

 

LetsEncrypt측에 전달할 나의 이메일을 적습니다.

만료 시기 도래 등 인증서에 특이사항이 있을 경우 향후 알려줄 수 있습니다.
이 기능은 리눅스 콘솔 버전 certbot과 완전히 동일하군요.

 

현재 IIS에서 작동중인 사이트를 선택합니다. 여러 곳에 쓰고 싶다면 여러 사이트를 모두 선택해도 되고, 사이트 선택 없이 발급만 할 수도 있습니다.
Request Certificate 버튼을 누르면 인증서 발급이 완료됩니다. Settings에 들어가서 갱신 일정도 올바른지 확인하세요.

이렇게 하면 IIS의 SSL 인증서에 LetsEncrypt가 올라가는 것을 확인할 수 있고, 향후에도 간단하게 변경할 수 있습니다.

단순히 HTTPS 통신에만 쓰는 것이 아니라, 원격 배포 기능과 FTP SSL 등 인증서가 필요한 분야가 많이 있으므로 폭넓게 활용할 수 있겠습니다.

한계

무료 버전은 5개의 사이트만을 관리할 수 있습니다. 프로 라이센스로 3개 사이트 더 추가하려면 약 50달러, 엔터프라이즈 라이센스로 100개 사이트 더 추가하려면 349달러네요. 여러 개 구매도 가능하다니 프로에 프로를 끼얹어도 되겠습니다.

문제 해결

  • 테스트 버튼을 눌러봤는데 실패할 수 있습니다. 외부 접속 체크시 DNS 확인이 올바르지 않을 수 있습니다. 인터넷 상황이 문제 없고 포트 바인딩이 되어 있으며 경로에 방화벽이 가로막지 않고 있다면, 과감히 Request Certificate를 눌러보세요.
  • 그 외에 Cloudflare 같은 DNS 서비스를 이용하고 있다면,  API Key를 발급받아서 넣고 이 앱에서 DNS-01 방식으로 체크를 요구할 수 있습니다. 이렇게 하면 서버의 파일 저장 공간에 임시 acme 테스트 없이 더 빠르고 문제 없이 도메인 소유 및 매치 여부를 확인할 수 있습니다. 와일드 카드 인증서(4 버전 이상) 발급시 DNS 인증이 필요할 것입니다.

Windows 2016 서버 구축

Windows Server 2016

은 제가 한 게 아닙니다. 그냥 저렴하게 샀어요. (클라우드의 시대! 관련 정보)

지금까지는 리눅스의 Ubuntu, CentOS 등에서 서버 구축을 LEMP 절차에 따라 진행해서 성공적으로 셋팅해왔죠. 허나 윈도우는 또 다른 도전입니다.

앞으로 무엇이 가능할지 더 찾아봐야겠습니다.

우선 IIS로 정통 셋팅하는 방법을 진행중입니다.

realLyrics / realLyrics+ 레알가사 (2011)

realLyrics playing screen
realLyrics

레알가사는 온라인 알송(ESTSoft의 앱) 서버에서 가사를 검색하여 사용자가 듣고 있는 음악과 싱크를 맞추어 표시해주는, Windows Phone용 음악 플레이어 앱입니다.

개발 동기

새로운 Windows Phone 7.5 Mango가 출시되어, 한국에도 출시될 조짐이 있을 무렵, 해외에서 구한 Samsung Omnia 7은 메탈 재질에 블랙 디자인, AMOLED를 갖고 있어서 아주 만족스러웠습니다. 하지만 사용할 앱이 없다는 치명적 상황 탓에, Windows Phone 스토어라는 무주공산을 차지하고자 야심차게 도전해보았습니다.

Zune의 디자인 코드를 이어받은 Windows Phone의 Metro Design은 영감의 보고였는데, 플레이어만큼은 기능이 너무 절제되어 있었습니다. 따라서, 기능을 보강하면서, 그 디자인 언어를 해치지 않는 방식으로 진행하고자, 가사를 보여주는 애플리케이션을 만들어보기로 결정했습니다.

개발 언어 및 도구

  • C# / XAML
  • Microsoft Visual Studio 2010
  • Windows Phone 7.1 SDK

“realLyrics / realLyrics+ 레알가사 (2011)” 더보기

SQL 뷰(View) 소개

뷰란, CREATE TABLE로 정의된 실제 테이블로부터 작성되는 가상 테이블을 말합니다. 뷰는 그저 가상 테이블일 뿐이므로, 내부의 데이터는 존재하지 않습니다. 뷰는 실제 테이블을 어떻게 보여줄까를 정의한 것이라고 볼 수 있습니다.

이미 사용하고 있습니다만, CREATE TABLE에서 정의된, 데이터가 들어 있는 테이블을 실제 테이블이라고 하며, 이 실제 테이블에서 만들어지는 가상 테이블을 뷰라고 부릅니다.

뷰의 장점

뷰의 실체는 SELECT 문에 의한 쿼리를 정의한 것입니다. 뷰에 접근하면, 정의된 쿼리가 실행되며, 실제 테이블에서 필요한 데이터가 나타납니다. 또한, 뷰에서 뷰를 정의하는 것도 가능합니다. 그러므로 미리 매번 입력하는 것이 귀찮고 복잡한 쿼리를 한 번 뷰로 정의해두면, 유저와 프로그램에서는 단순한 쿼리를 실행하는 것으로 해결됩니다.

이러한 개발 노력의 경감이라고 하는 관점 이외에, 보안면에서도 장점이 있습니다. 예를 들어, 실제 테이블의 데이터 속에 일반 유저에게 보이고 싶지 않은 것이 있는 경우, 실제 데이터에 액세스 권한을 일반 유저에게 제공하는 것은 불가합니다. 그러나 보이고 싶지 않은 데이터를 제외한 뷰를 정의하는 것으로, 일반 유저에게도 실제 테이블의 데이터를 이용하게 할 수 있게 됩니다.

뷰의 작성

뷰를 작성하기 위해서 CREATE VIEW 문을 이용합니다. 기본 구조는 다음과 같습니다.

CREATE VIEW 뷰 이름 [(칼럼명, 칼럼명, .....)] AS
SELECT文
[WITH CHECK OPTION];

뷰 이름 이후에는, 추출되는 데이터의 칼럼명을 기술합니다. 칼럼명을 생략한 경우, SELECT 문에서 지정한 칼럼의 이름이 그대로 사용됩니다. SELECT 문에서 연산자를 사용한 경우와 미리 칼럼명을 지정한 경우에 명시적으로 기술하는 것입니다.

뷰 이름과 칼럼명 다음에는, AS에 이어서 SELECT 문에 의한 쿼리를 기술합니다. 이 쿼리 결과가 이 뷰의 데이터라는 것입니다. [WITH CHECK OPTION]은 뷰 갱신에 관련되는 옵션입니다. 뷰의 갱신에 대해서는 아래에서 설명합니다.

이 문장의 SQL 샘플에서 앞장까지 쓰이고 있던 수주표, 고객표, 상품표를 실제 테이블로 사용합니다. sample.21-1에서 v_수주라고 하는 이름의 뷰를 정의하고, 마지막에 뷰의 내용을 확인하고 있습니다.

/* 뷰의 작성 */
CREATE VIEW v_수주 AS
SELECT JJ.수주번호, KK.고객이름, SS.상품명,
JJ.수주개수, JJ.납품일
FROM 수주표 JJ, 고객표 KK, 상품표 SS
WHERE JJ.고객코드 = KK.고객코드
AND JJ.상품코드 = SS.상품코드;
 
/* 확인 */
SELECT JJ.수주번호, KK.고객이름, SS.상품명,
JJ.수주개수, JJ.납품일
FROM 수주표 JJ, 고객표 KK, 상품표 SS
WHERE JJ.고객코드 = KK.고객코드
AND JJ.상품코드 = SS.상품코드;

정의한 뷰에서 특정 행과 열을 출력할 수 있습니다. sample.21-2는 정의한 v_수주에서, 수주개수가 100 이상인 경우를 선택하여, 그 고객 이름과 상품명 및 수주 개수를 출력하는 것입니다.
실행결과

고객명 상품명 수용자수
──────────── ────── ───────
KUROKIYA JUICE 300
ONSIDE BEER 200
KUSHINANA BEER 150
ONSIDE WINE 110
KUROKIYA TEA 250
KUSHINANA BEER 135
KUROKIYA BEER 290
KUSHINANA BEER 175

표준규격에 대해서

표준 SQL 규격에 대해서는, SQL89부터 가능합니다. SQL92에서 CHECK OPTION, LOCAL, CASCADE의 기능 확장이 행해집니다. SQL99에서 더욱 기능 강화가 이뤄져서, 일정 조건 하에서 뷰에서 실제 표의 데이터 갱신이 가능해졌습니다. 또한 SQL89에서 뷰를 작성할 수 있는 한편, DROP 스테이트먼트가 없는 탓에 삭제할 수 없습니다.

뷰의 삭제

뷰 삭제를 할 때는, 다음과 같이 SQL문을 기술합니다. (DROP 스테이트먼트 상세)

DROP VIEW 뷰 이름;

실습 과제

  1. 다음 테이블로 이하 조건에 맞는 쿼리를 만들어봅시다.
  • 이름을 하나의 칼럼으로 만들어서 fullname으로 지정
  • Birthdate가 2001-09-01보다 이전인 경우만 표시
id first_name last_name email birthdate added
1 Bonnie Medhurst [email protected] 1999-07-26 1982-05-01 21:32:19
2 Vincenza Streich [email protected] 2006-01-30 2000-07-15 18:19:18
3 Carter Kilback do’[email protected] 1998-12-07 1998-08-14 06:13:52
4 Mariano Stroman [email protected] 1996-06-18 2008-04-06 14:43:43
5 Deondre Kerluke [email protected] 1994-04-10 2008-06-26 22:02:19
6 Gia Towne [email protected] 1988-07-13 1982-03-22 03:16:39
7 Margarett Beahan [email protected] 2008-01-22 2010-09-12 08:59:33
8 Gilda Brekke [email protected] 1981-09-18 2016-04-14 01:17:38
9 Zackary Cummerata [email protected] 2001-05-27 2003-05-23 21:18:54
10 Kory Wiegand [email protected] 2010-03-16 1992-03-22 04:14:31
11 Vinnie Zboncak [email protected] 2016-06-23 2014-12-29 20:55:25
12 Carmella Bogan [email protected] 1978-06-10 1993-01-17 08:43:08
13 Vance Rice [email protected] 1996-10-09 1999-09-14 15:27:08
14 Coleman Maggio [email protected] 1999-11-22 2001-05-01 05:42:36
15 Patricia Zieme [email protected] 1978-11-18 1987-07-21 18:44:25
16 Jada Beer [email protected] 1991-07-17 1997-10-08 09:41:57
17 Kianna Torphy [email protected] 1994-03-17 2011-11-20 20:15:40
18 Maegan Harvey [email protected] 1979-07-18 2010-10-06 20:52:03
19 Winona Welch [email protected] 1974-10-28 2010-09-02 22:05:57
20 Queen Mosciski [email protected] 1983-05-23 1985-10-09 08:51:49

CREATE VIEW scit_view AS
SELECT (first_name || last_name) AS fullname, email
FROM scit_user
WHERE birthdate < to_date('2001-09-01','YYYY-MM-DD');

SELECT fullname, email FROM scit_view;
  1. WHERE에 지정된 조건에 맞는 아이템이 원래 테이블에서 변경되면, 뷰 결과는 어떻게 됩니까?
  2. Oracle을 포함하여, 최근 데이터베이스 시스템에서 INSERT, UPDATE, DELETE가 가능합니다만, 이러한 DML 조작이 불가능한 경우를 생각해봅시다.

 

이 본문은 Techscore 원문을 가공하여 발표를 위해 준비한 자료입니다.

와사비망고 USB Type C Gen 2 케이블 수령

와사비망고 USB Type-A – Type-C Gen 2 케이블

와사비망고에서 새로 출시한 이 케이블은 예전 USB 3.0으로 불리던 지금의 3.1 Gen 1 수준에 머무르던 기존의 케이블 수준을 크게 상회하여 Gen 2라는 새로운 규격을 지원할 수 있는 물건입니다.

아직까지 Gen 2를 제대로 지원하는 기기도 부족한 현실이긴 하나, 이런 부분이야말로 소모품이 그 자리를 메꿔줄 필요가 있습니다. 저렴하게 주변 기기가 자리 잡아야 규격의 생태계도 자리잡기 마련이니까요.

물론 하위 호환성도 있고 단순히 폰을 충전하는데 써도 하등의 문제는 없습니다.

경비실을 스루-하고 뒤늦게 찾아오느라 본의 아니게 인증이 늦어졌습니다.

당장 이것을 써보지 아니할 수가 없군요.

풍성한 스티커는 기글러의 충성심을 인증하는데 유용할 것입니다.

리사이즈로 글씨를 알아보기 어려워지긴 하였으나, 상당히 친절한 안내 문구라는 것은 명확합니다.

USB 포장이 간소하고 뜯기 편합니다. 제품을 쓸데없이 뜯기도 힘든 플라스틱 내부에 봉할 필요는 없는 것이죠.

왜냐하면 이 제품이 워낙 두껍고 단단해서 집어던져도 괜찮을 거 같거든요.(…)

케이블 표면에 적힌 문구로 80도, 30V, VW-1, USB 3.1 HIGH SPEED라고 표기된 내용이 눈에 띕니다.

케이블이 얼마나 여유로운 스펙 기준을 갖고 있는지, 믿음직한지 알 수 있는 부분입니다.

갤럭시 노트 8이 고속 충전을 인식합니다. 이 녀석은 QC 2.0만 지원하고 Adaptive Charge라는 갈라파고스를 자랑하지만 와사비망고는 이를 가리지 않고 고속으로 충전해버리죠.

USB 테스터에 찍힌 전력량은 11W입니다.

볼트가 높아지면 심장도 벌렁벌렁 뛰지만, 그간 케이블은 전압이 올라가도 전류가 제자리 걸음을 하여 답답하였죠.

특히 12W에 커넥터 주위가 열받기 시작하는 바로 아래 은색 케이블에 대한 불만과 불안을 떠올리면, 와사비망고는 타 케이블과 확연히 다르단 걸 알 수 있습니다.

그리고 뒤늦게 서랍에서 꺼낸 루미아 950을 충전합니다.
주인이 자꾸 까먹어서 맨날 방전되네요.

전압이 왜 5V에서 더 많이 안 뛰나 했는데 QC 미지원이었군요.
(Type-C Fast Charge 1.5A만 만족)

아무튼 와망 케이블은 이렇게 주어진 역할을 충실히 해내고 있습니다.

특징으로 무척 강력한 결합력을 들 수 있습니다.
끝까지 끼우면 기기 통째로 포트가 빠질까 두렵기까지 할 정도로 잘 붙습니다.
그리고 C-Type이 헐거운 케이블이 적지 않은데 이것은 양쪽 모두 흔들림 없이 붙는 게 인상적입니다.

이 글은 기글 하드웨어에서 이벤트로 지원받은 물건을 간단히 소감 형식으로 작성한 것입니다.
https://gigglehd.com/gg/2634311

python

certbot 등 python에서 모듈 에러가 뜬다면 꼭 살펴볼 점

Letsencypt (certbot) 설정을 업데이트하면서, 이전에 한 Ubuntu의 대형 시스템 업데이트가 이것저것 망가뜨렸음을 알 수 있었다.

사실 리눅스의 상당 부분은 python 코드가 지탱하고 있다고 해도 과언이 아닌데(심지어 yum이나 apt-get도 포함한다), certbot 또한 예외가 아니다.

그냥 실행만 했을 뿐인데, 잘 되던 실행 파일이 이런 무참한 에러를 발생시키고 있었다.


:~$ sudo certbot
Traceback (most recent call last):
  File "/usr/bin/certbot", line 11, in 
    load_entry_point('certbot==0.21.1', 'console_scripts', 'certbot')()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 561, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2631, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2291, in load
    return self.resolve()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2297, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python3/dist-packages/certbot/main.py", line 10, in 
    import josepy as jose
  File "/usr/lib/python3/dist-packages/josepy/__init__.py", line 41, in 
    from josepy.interfaces import JSONDeSerializable
  File "/usr/lib/python3/dist-packages/josepy/interfaces.py", line 8, in 
    from josepy import errors, util
  File "/usr/lib/python3/dist-packages/josepy/util.py", line 4, in 
    import OpenSSL
  File "/usr/lib/python3/dist-packages/OpenSSL/__init__.py", line 8, in 
    from OpenSSL import crypto, SSL
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 16, in 
    from OpenSSL._util import (
  File "/usr/lib/python3/dist-packages/OpenSSL/_util.py", line 6, in 
    from cryptography.hazmat.bindings.openssl.binding import Binding
  File "/usr/lib/python3/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 156, in 
    Binding.init_static_locks()
  File "/usr/lib/python3/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 137, in init_static_locks
    cls._ensure_ffi_initialized()
  File "/usr/lib/python3/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 124, in _ensure_ffi_initialized
    cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
  File "/usr/lib/python3/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 84, in build_conditional_library
    if not getattr(lib, condition):
AttributeError: cffi library '_openssl' has no function, constant or global variable named 'Cryptography_HAS_MEM_FUNCTIONS'

cffi library ‘_openssl’ has no function, constant or global variable named ‘Cryptography_HAS_MEM_FUNCTIONS’

보통 함수가 오류가 나고, 라이브러리를 제대로 된 것을 내놓으라는 위와 같은 오류가 발생하면,
파이썬 모듈을 다시 설치하면 해결되기 마련이다.

$ pip install cryptography

그러나 이 경우, 아무리 pip에서, 구글링했던 대로 cryptography를 다시 설치하더라도 문제가 해결될 기미가 보이지 않았다.

-U 옵션을 붙여서 강제 업그레이드를 하든말든 변화는 없었다.

그러다가 python 2.7이라는 표기와 python3라는 표기에 주목하게 되었다. 이미 2.7과 3에 3.5로 맨날 갈아엎으면서 기존 호환성이 무너지다보니 요즘 리눅스에선 다 설치하는게 추세가 됐다는 예의 그 문제다.

pip 실행 파일은 python 2.7에 대해서만 수정하고 있었으나, certbot은 python3를 필요로 하고 있으며 정상적으로 python3에서 실행될 수 있도록 다음과 같은 스크립트를 갖고 있다.

#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'certbot==0.21.1','console_scripts','certbot'
__requires__ = 'certbot==0.21.1'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(
        load_entry_point('certbot==0.21.1', 'console_scripts', 'certbot')()
    )

이제 해답은 명확해졌다. pip가 2.7에 모듈을 무의미하게 지웠다깔았다 하는 사이, python3는 문제가 전혀 해결되지 않았던 것이다.

$ sudo apt-get install python3-setuptools
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  python-setuptools-doc
The following NEW packages will be installed:
  python3-setuptools
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 215 kB of archives.
After this operation, 944 kB of additional disk space will be used.
Get:1 http://ppa.launchpad.net/certbot/certbot/ubuntu xenial/main amd64 python3-setuptools all 33.1.1-1+certbot~xenial+1 [215 kB]
Fetched 215 kB in 1s (109 kB/s)
Selecting previously unselected package python3-setuptools.
(Reading database ... 109834 files and directories currently installed.)
Preparing to unpack .../python3-setuptools_33.1.1-1+certbot~xenial+1_all.deb ...
Unpacking python3-setuptools (33.1.1-1+certbot~xenial+1) ...
Setting up python3-setuptools (33.1.1-1+certbot~xenial+1) ...

easy_install python3 버전을 깔기 위해 ubuntu에선 이 명령을 입력하면 된다. 설치된 easy_install3를 활용하여 pip도 같이 설치한다.

$ sudo easy_install3 pip
Searching for pip
Reading https://pypi.python.org/simple/pip/
Downloading https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9
Best match: pip 9.0.1
Processing pip-9.0.1.tar.gz
Writing /tmp/easy_install-wmqoi3hf/pip-9.0.1/setup.cfg
Running pip-9.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-wmqoi3hf/pip-9.0.1/egg-dist-tmp-b7xxe23x
warning: no previously-included files found matching '.coveragerc'
warning: no previously-included files found matching '.mailmap'
warning: no previously-included files found matching '.travis.yml'
warning: no previously-included files found matching '.landscape.yml'
warning: no previously-included files found matching 'pip/_vendor/Makefile'
warning: no previously-included files found matching 'tox.ini'
warning: no previously-included files found matching 'dev-requirements.txt'
warning: no previously-included files found matching 'appveyor.yml'
no previously-included directories found matching '.github'
no previously-included directories found matching '.travis'
no previously-included directories found matching 'docs/_build'
no previously-included directories found matching 'contrib'
no previously-included directories found matching 'tasks'
no previously-included directories found matching 'tests'
creating /usr/local/lib/python3.5/dist-packages/pip-9.0.1-py3.5.egg
Extracting pip-9.0.1-py3.5.egg to /usr/local/lib/python3.5/dist-packages
Adding pip 9.0.1 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip3 script to /usr/local/bin
Installing pip3.5 script to /usr/local/bin

Installed /usr/local/lib/python3.5/dist-packages/pip-9.0.1-py3.5.egg
Processing dependencies for pip
Finished processing dependencies for pip

설치가 잘 된 듯 하니, 셸에서 실행 가능한지 확인해보자.

$ which pip3
/usr/local/bin/pip3

이처럼 절대 경로를 잘 표시해주고 있다. pip3 명령을 통해 cryptography 모듈을 깔아보자. 버전으로 난리치지 않게 U 옵션을 잊지 말고 넣어서, 강제로 업그레이드를 하도록 하자.

$ sudo pip3 install -U cryptography
The directory '/home/yeon/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/yeon/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting cryptography
  Downloading cryptography-2.1.4-cp35-cp35m-manylinux1_x86_64.whl (2.2MB)
    100% |████████████████████████████████| 2.2MB 451kB/s
Collecting idna>=2.1 (from cryptography)
  Downloading idna-2.6-py2.py3-none-any.whl (56kB)
    100% |████████████████████████████████| 61kB 3.7MB/s
Collecting asn1crypto>=0.21.0 (from cryptography)
  Downloading asn1crypto-0.24.0-py2.py3-none-any.whl (101kB)
    100% |████████████████████████████████| 102kB 3.1MB/s
Collecting cffi>=1.7; platform_python_implementation != "PyPy" (from cryptography)
  Downloading cffi-1.11.4-cp35-cp35m-manylinux1_x86_64.whl (419kB)
    100% |████████████████████████████████| 419kB 833kB/s
Requirement already up-to-date: six>=1.4.1 in /usr/lib/python3/dist-packages (from cryptography)
Collecting pycparser (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography)
  Downloading pycparser-2.18.tar.gz (245kB)
    100% |████████████████████████████████| 256kB 1.8MB/s
Installing collected packages: idna, asn1crypto, pycparser, cffi, cryptography
  Found existing installation: idna 2.5
    Uninstalling idna-2.5:
      Successfully uninstalled idna-2.5
  Found existing installation: asn1crypto 0.22.0
    Uninstalling asn1crypto-0.22.0:
      Successfully uninstalled asn1crypto-0.22.0
  Running setup.py install for pycparser ... done
  Found existing installation: cryptography 1.9
    Uninstalling cryptography-1.9:
      Successfully uninstalled cryptography-1.9
Successfully installed asn1crypto-0.24.0 cffi-1.11.4 cryptography-2.1.4 idna-2.6 pycparser-2.18

무언가 잘 진행되는 것 같이, 진행률 표시도 된다.

$ sudo certbot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------

이후, 거짓말처럼 모든 것이 잘 작동하고 있다.

Oracle에서 관리자 비밀번호 찾기와 계정 잠금 풀기

자연스럽게 접속했더니 ORA-28000 에러가 난다. 아니면 ORA-01017 invaild username/password가 뜬다면? system 권한만이 상황을 반전시킬 수 있을 것이다.

Windows에서 흔하게 Oracle 을 설치했다고 가정한 환경에서 진행한다.

계정이 잠겼어요!

SQL> conn 아이디/비번
ERROR:
ORA-28000: the account is locked

이러한 오류가 발생하는 경우가 있어서 아무런 동작이 먹히지 않을 때가 있다.

이는 연속하여 비밀번호를 틀린 경우 계정이 잠기도록 기본적으로 설정이 되어 있기 때문이다.

이럴 때 시스템 계정으로 접근하여 풀어줘야 한다.

시스템 비밀번호를 잊어버렸어요!

SQL> conn system
Enter password:
ERROR:
ORA-01017: invalid username/password; logon denied

산 넘어 산이다. 이럴 때는 sysdba 권한으로 접속하면 해결된다고 한다.

비밀번호도 없이 쓱 들어가지는게 신기하고 이래도 되나 싶지만, OS가 관리자 권한으로 로그인되어 있어야만 동작한다고 한다.

시스템 제어가 넘어갔을 때 DB도 동시에 넘어가지 않도록 sysdba 권한에 대한 추가 설정이 나중에 필요할 듯 싶다.

방법은 다음과 같다.

SQL> conn /as sysdba
Connected.

상당히 싱겁게 해결되었다.

잊어버린 계정에 대한 비밀번호 재지정

다음으로 각각의 비번을 다시 설정해보자.

SQL> alter user system identified by 새로운비밀번호;

User altered.

이 방법으로 새로운 비밀번호로 설정을 완료할 수 있다. system 부분에 hr 등 계정을 넣으면 바로 비밀번호가 변경된다.

SQL문과 유사한 표기가 많이 나타난다.

그래서 잠긴 계정을 이제 풀어보자

잠깐. 진짜 잠기긴 한 걸까? 다음 코드를 쓰면 알 수 있다.

SQL> select username, account_status, lock_date from dba_users

결과를 적으면 너무 길어지니까 스킵한다.

SQL> alter user hr account unlock;

User altered.

이렇게 해서 hr 계정을 언락할 수 있었다.

결론

  • 비밀번호를 잊지 말자
  • 잠기지 않도록 DB 접근을 어렵게 하자
  • 절대 관리자 계정으로 Oracle 콘솔을 열 수 없게 하자 OR sysdba 설정을 손보자

WebSocket 오늘의 삽질

브라우저의 개발자 도구를 보면, 제일 먼저 보이는 것은 요소 검사, Inspect라고 불리는 것이 있는데요. 그거 말고 네트워크 탭이 유용한 경우가 꽤 있습니다.

주로, 앱을 만들 때, 웹의 정보를 끌어들이기엔 HTML 요소를 분석하는 것도 방법이지만, 스크립트를 통해서 실시간으로 정보를 비동기로 가져오는 경우가 더 많기 때문입니다.

특히 유용한 정보는 정적으로 들어있는 경우가 잘 없죠.

이 때 네트워크 탭에서 딱히 별다른 것이 잡히지 않는데도 활발하게 데이터가 갱신되는 페이지를 볼 수 있습니다.

요즘 가장 핫한 가상 화폐 시세 같은 경우가 바로 거기에 해당하겠네요. 새로고침을 하지 않아도 즉시즉시 눈앞에 드러나고 있죠.

이 경우, HTTP 연결을 통해 매번 비동기로 가져오기엔 비용이 크기 때문에 HTML5에서 도입된 WebSocket이란 걸 쓴다고 합니다.

WebSocket은 추가 연결 과정, 헤더 전송이 불필요하므로 빠르게 실시간으로 정보를 수신하기에 매우 유용합니다.

이런 흐름에 발맞추어, 브라우저에서도 관련 지원 기능을 넓히고 있습니다.

Chrome이 그 대표적 사례로, Canary에서 먼저 선보인 기능이지만 진작에 정식 버전에도 WebSocket을 분석할 수 있게 했습니다.

그러나 실망스러운 화면만 나타나더군요.

Nothing Here
Nothing Here

이 상황을 어찌 해야 할까요.

Chrome을 잘못 설치했나, 그렇게 고민에 휩싸이면서 Firefox도 살펴봤는데 이쪽도 가관입니다.

플러그인이 업데이트 되지 않아서 쓸 수 없었습니다(…)

그래서 마침내 구글링을 통해 도달한 해답은 이것이었습니다.

Chrome Dev Tools WebSocket
Chrome Dev Tools WebSocket

출처: https://stackoverflow.com/questions/44533111/chrome-59-websocket-frames-no-longer-visible-in-devtools

더 이상의 말이 필요 없습니다.

이 덕분에 무사히 데이터 분석을 마칠 수 있었습니다.

이제 남은 과제는 이걸 어떻게 클라이언트에서 구현하느냐 일 것 같습니다.

갑자계산

C#으로 60갑자(간지干支) 계산식을 세워보자

간지 (干支) : 십간(十干)과 십이지(十二支)를 합쳐서 60주기로 하는 수사입니다.

발상

60간지를 나열한 자료는 쉽게 인터넷 검색으로 구할 수 있지만, 그걸 계산하는 건 많지 않습니다.

요즘 Java를 열심히 배우고 있는 입장에서, 기존에 하던 C#를 까먹어버리면 곤란한 관계로, C#을 오랜만에 활용하여 실력을 썩히지 않도록 노력해야겠다고 다짐했습니다.

그리하여 타임어택 같은 느낌으로 도전하였습니다.

30분 안에 기능 하나는 완성해야 하지 않겠습니까!

접근

수학적인 기존의 지식을 활용하는 것도 유용해보이지만, 배열의 특성을 최대한 활용해보기로 했습니다.

언제 다시 보더라도 쉽게 이해할 수 있는, 구현이 어렵지 않은 코드를 지향하였습니다.

우선, 간지를 각각 배열로 적어봅시다.

static string[] gap = new string[] { "갑", "을", "병", "정", "무", "기", "경", "신", "임", "계" };
static string[] ja = new string[] { "자", "축", "인", "묘", "진", "사", "오", "미", "신", "유", "술", "해" };

어렵지 않습니다.

구현

연도를 간지로 변환

연도를 간지로 바꿔봅시다. 생각하기 편하게 올해(2017, 정유년)를 기준으로 생각해봅니다.

올해와 목표년도의 차이를 구하고 단순히 각각의 배열 길이로 나누어 나머지를 구하면 됩니다. 그 다음 올해의 간지만큼 더해주면 끝이죠.

하지만 여기서 의외로 연도를 간지로 바꾸는데는 구현에 약간의 애를 먹었는데, 앞으로는 문제 없이 구하는데 거꾸로는 엉뚱한게 나왔던 것입니다.

고민하다가 원인은 음수 처리에 있었다는 걸 알았습니다.

private static string YearToGapja(int i) {
            int cha = i - 2017;
            //기준점을 2017년으로 잡아봅니다.
            int gap_cha = cha % gap.Length;
            int ja_cha = cha % ja.Length;

            gap_cha = (gap_cha + 3) % gap.Length;
            ja_cha = (ja_cha + 9) % ja.Length;

            if (gap_cha < 0) {
                gap_cha = gap.Length + gap_cha;
            }
            if (ja_cha < 0) {
                ja_cha = ja.Length + ja_cha;
            }

            return gap[gap_cha] + ja[ja_cha];
        }

음수 처리로 한 번 더 길이를 더해주면 끝에서부터 음수로 세어간 위치를 구할 수 있습니다. 이렇게 하면 몇 년이고 틀리지 않고 다 구할 수 있죠.

아, 여기서 옥에티가 있군요. 기원전을 지원하는 것입니다. 그냥 해서는 0년이 포함되어버리죠.

private static int MinusToBC(int i) {
    if(i < 0) { //
       return ++i;
    }else if(i == 0) {
       return int.MinValue;
    }
    return i;
}

이렇게 음수에 한해서는 입력값을 실제보다 1 더해주면 됩니다.

0을 입력한 경우를 별도로 구분하기 위해 int.MinValue로 넣어줬습니다. 이는 Int32 범위의 최하 숫자를 가져올 수 있는데, 이걸로 무효한 숫자로 처리하면 크게 유용성에 간섭받지 않고 잘 확인할 수 있습니다.

int.MinValue와 같으면 계산을 포기한다는 구절을 넣는 것으로 충분하죠.

한편, Console.ReadLine()을 통해 입력값을 받는 만큼, 이것이 유효한 숫자인지 판별할 필요가 있습니다.

do {
    Console.Write("희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: ");
    input = Console.ReadLine();
} while ((!int.TryParse(input, out i) && !isGapja(input)) || input == "0");

이를 통해 input이 숫자가 아니거나, 갑자가 아닌 경우 또는 0을 입력한 경우 모두 다시 읽으려고 시도하겠군요.

int.TryParse는 Parse 실패시에 out i 값이 0이라고 합니다.

private static bool isGapja(string input) {
            if (input.Length == 2) {
                if(!(gap.Contains(input[0].ToString()))) {
                    return false;
                }
                if (!(ja.Contains(input[1].ToString()))) {
                    return false;
                }
                return true;
            }
            return false;
        }

위에서 등장한 IsGapja라는 함수를 만들어두면 반복문을 돌 때 input의 간지 유효성을 확인하고 실제 갑자를 갖고 있는지 확인할 수 있습니다.

결과 확인

여기까지 하면 결과가 시원하게 나옵니다.

희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: 2017
결과: 정유

희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: 2002
결과: 임오

희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: 1988
결과: 무진

와우. 이렇게 하였더니 목표 30분보다 10분 빠르게 끝났네요.

하지만 15분 냉장고를 부탁해 컷에는 실패했습니다. 다음에는 분발합시다!

간지를 연도로

그 다음으로 간지를 연도로 변환해보겠습니다. 60년마다 돌아오니까 환갑이라고 하죠. 아무래도 여러 번 있을 것이고, 시작 년도와 끝 년도도 중요하겠죠.

유연한 적용을 위해서 일부러 시작 년도와 끝 년도를 매개변수로 받았습니다.

그리고 이제 끝없는 고민을 합니다. 위의 간지 변환 사례를 역으로 방정식을 세우면 그만일까요?

아무래도 머리가 핑핑돌고 문제가 생겼을 때 어떤 방식을 써야할지 수알못에게 두려움이 비칩니다.

이럴 때는 컴퓨터를 믿고 왕도를 걸어보기로 합니다. 사실 목표 간지와 기준 간지의 차이만큼을 알고 있으면 그 +/- 60만 반복하면 결과가 됩니다.

그러나 목표 간지와 기준 간지 차이를 구하기엔, 쉽지 않습니다. 계산식을 더 많이 고민하면 되겠지만요.

수학자가 아닌 프로그래머에겐, 코드가 더 많은 답을 줍니다.

private static string[] EnumGapja() {
            string[] s = new string[60];
            for(int i = 0; i < 60; i++) {
                s[i] = gap[i % gap.Length] + ja[i % ja.Length];
            }
            return s;
        }

이렇게 하면 위 전역변수를 활용하여 60갑자가 뚝딱 완성됩니다.

나머지가 끊임없이 찬조출연하더군요.

private static int[] GapjaToYear(string input, int min, int max) {
            string[] eg = EnumGapja();
            int ifrom_gapja=Array.IndexOf(eg, input);

            //서기 4년은 갑자년.
            //4*60n=갑자
            //4*60n+ifrom_gapja=갑자+ifrom_gapja
            List ilist = new List();
            for (int i = 4 + ifrom_gapja; i < max; i+=60) {
                if(i < min) {
                    continue;
                }
                ilist.Add(i);
            }

            return ilist.ToArray();
        }

이제 한없이 길어지던 코드가 한결 간결해졌습니다.

단순히 60갑자 목록에서 index의 차이만 알게 되는 것으로 추가해야할 년도를 알 수 있습니다.

갑자년이 서기 4년이라고 합니다. 이 갑자년과의 차이 = index라는 걸 쉽게 예측할 수 있으니까요.

min년부터 max년까지 반복문을 돌리면 그만이겠습니다.

희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: 무자
28년 88년 148년 208년 268년 328년 388년 448년 508년 568년 628년 688년 748년 808년 868년 928년 988년 1048년 1108년 1168년 1228년 1288년 1348년 1408년 1468년 1528년 1588년 1648년 1708년 1768년 1828년 1888년 1948년 2008년 2068년 2128년 2188년 2248년 2308년 2368년 2428년 2488년 2548년 2608년 2668년 2728년 2788년 2848년 2908년 2968년 3028년 3088년 3148년 3208년 3268년 3328년 3388년 3448년 3508년 3568년 3628년 3688년 3748년 3808년 3868년 3928년 3988년 4048년 4108년 4168년 4228년 4288년 4348년 4408년 4468년 4528년 4588년 4648년 4708년 4768년 4828년 4888년 4948년 5008년 5068년 5128년 5188년 5248년 5308년 5368년 5428년 5488년 5548년 5608년 5668년 5728년 5788년 5848년 5908년 5968년 6028년 6088년 6148년 6208년 6268년 6328년 6388년 6448년 6508년 6568년 6628년 6688년 6748년 6808년 6868년 6928년 6988년 7048년 7108년 7168년 7228년 7288년 7348년 7408년 7468년 7528년 7588년 7648년 7708년 7768년 7828년 7888년 7948년 8008년 8068년 8128년 8188년 8248년 8308년 8368년 8428년 8488년 8548년 8608년 8668년 8728년 8788년 8848 년 8908년 8968년 9028년 9088년 9148년 9208년 9268년 9328년 9388년 9448년 9508년 9568년 9628년 9688년 9748년 9808년 9868년 9928년 9988년

:)

전체 소스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gapja {
    class Program {
        //4 5 6 7 8 9 0 1 2 3
        static string[] gap = new string[] { "갑", "을", "병", "정", "무", "기", "경", "신", "임", "계" };
        static string[] ja = new string[] { "자", "축", "인", "묘", "진", "사", "오", "미", "신", "유", "술", "해" };
        static void Main(string[] args) {
            //2017 = 정유년 = 4/9

            while (true) {
                string input = ""; int i = 0;
                do {
                    Console.Write("희망 서력 년도(기원전=>마이너스) 또는 갑자 입력: ");
                    input = Console.ReadLine();
                } while ((!int.TryParse(input, out i) && !isGapja(input)) || input == "0");
                i = MinusToBC(i);
                if(i != int.MinValue) {
                    Console.WriteLine("결과: {0}", YearToGapja(i));
                } else {
                    var result = GapjaToYear(input, 1, 10000);
                    foreach(var r in result) {
                        Console.Write("{0}년 ",r);
                    }
                }
                Console.WriteLine();
            }
        }

        private static bool isGapja(string input) {
            if (input.Length == 2) {
                if(!(gap.Contains(input[0].ToString()))) {
                    return false;
                }
                if (!(ja.Contains(input[1].ToString()))) {
                    return false;
                }
                return true;
            }
            return false;
        }

        private static int MinusToBC(int i) {
            if(i < 0) { //
                return ++i;
            }else if(i == 0) {
                return int.MinValue;
            }
            return i;
        }

        private static string YearToGapja(int i) {
            int cha = i - 2017;
            //기준점을 2017년으로 잡아봅니다.
            int gap_cha = cha % gap.Length;
            int ja_cha = cha % ja.Length;

            gap_cha = (gap_cha + 3) % gap.Length;
            ja_cha = (ja_cha + 9) % ja.Length;

            if (gap_cha < 0) {
                gap_cha = gap.Length + gap_cha;
            }
            if (ja_cha < 0) {
                ja_cha = ja.Length + ja_cha;
            }

            return gap[gap_cha] + ja[ja_cha];
        }

        private static string[] EnumGapja() {
            string[] s = new string[60];
            for(int i = 0; i < 60; i++) {
                s[i] = gap[i % gap.Length] + ja[i % ja.Length];
            }
            return s;
        }

        private static int[] GapjaToYear(string input, int min, int max) {
            string[] eg = EnumGapja();
            int ifrom_gapja=Array.IndexOf(eg, input);

            //서기 4년은 갑자년.
            //4*60n=갑자
            //4*60n+ifrom_gapja=갑자+ifrom_gapja
            List ilist = new List();
            for (int i = 4 + ifrom_gapja; i < max; i+=60) {
                if(i < min) {
                    continue;
                }
                ilist.Add(i);
            }

            return ilist.ToArray();
        }
    }
}
Servers

VPS를 고려하게 되는 이유, 저렴한 VPS 업체 비교

2020-12-12 추가: 이 글은 업데이트되지 않았으므로 최신 정보가 아닐 수 있습니다. 현재 서버는 Amazon Lightsail을 사용하고 있습니다.

웹 호스팅이 만능이 아닌 이유

웹 호스팅은 꽤 단순합니다. 그냥 사이트를 만들겠다고 마음 먹고 호스팅 업체에 신청하면 저렴한 옵션으로 만들어주죠.

이를테면, Cafe24의 경우엔 신청료가 별도로 있긴 하지만 한달 500원짜리까지도 있습니다. FTP로 접속해서 파일만 올리면 그야말로 홈페이지 셋팅 완료입니다.

이 과정도 생략하기 위해 WordPress나 제로보드 XE, 그누보드도 설치 지원해주는 업체가 많습니다. 이런 곳은 키보드도 별로 두들기지 않고 뚝딱 서버 완성입니다.

하지만 그렇게 해서 뿌듯하게 자신의 사이트를 만든 K씨(갑자기 사례자 등장?)
그는 디스크 사용량만을 고려하여 최저 플랜으로 웹 호스팅을 신청한 다음, 자신의 포트폴리오 사이트를 올려놓고, 면접 이력서를 여러 군데 넣고 본격적인 구직에 뛰어들었습니다.

어느 날, 취직 커뮤니티(Naver CAFE)를 방문한 K씨.

자신의 포트폴리오가 우수 사례로 공유되고 있다는 걸 알게 되자, 내심 뿌듯해했는데요.
그리고 얼마 가지 않아 고작 4번째 댓글에서 생각지도 못한 내용을 발견하게 되었습니다.

안 들어가지는데요.

어라? 하고 자신의 포트폴리오 사이트를 들어가보니, 반갑게 맞아준 건 이런 페이지였습니다.

카페24 트래픽 초과 페이지
카페24 트래픽 초과 페이지

부랴부랴 플랜을 업그레이드하려고 보니, 가격이 월 몇 만원까지 뛰어오르는군요. 트래픽 리셋을 매일매일 유료로 눌러주는 것도 대안이 되지 못합니다.

넉넉한 트래픽과 여유로운 공간, 이 두 가지를 노리려면 역시 가정집에 개인 서버라도 돌려야 하는 걸까요?
슬며시 전기료 걱정도 떠오르는데요.

VPS는 조금만 부지런하면 가장 유리한 옵션

그런 K씨의 지인은 VPS1를 소개해주었습니다. VPS란 것도 처음 듣는데, 들어보니 원격지에 서버 하나가 생기는 거라 하더군요.

호스팅 서버랑 뭐가 다르지 했는데, 이건 온전히 컴퓨터 한 단위를 다룰 수 있다고 합니다.

월 몇 십만 원에서 백만 원인 서버 호스팅은 많이 비싼데요. 이건 서버를 쪼개서 서버로 만든다고 합니다(!)

서버를 한 컴퓨터 안에서 여럿으로 나눌 수 있는 건 가상화 기술이 진보했기 때문입니다.
컴퓨터 속 컴퓨터로 명령어를 별도로 처리해야 했던 과거와 달리 CPU와 주요 장비들이 처음부터 가상화를 대비하고 만들어져서 성능의 저하를 최소화2한다고 합니다.

서버를 빌리는 것이니 가격도 상당하겠지만, 서버는 자유로운 용도로 활용할 수 있으므로 경우에 따라 더 유리할 수 있습니다. 특히 기본 트래픽이나 용량 제공이 그리 적지 않다는 점이 큰 매력입니다.

밑에서 서술하겠지만, 최소 트래픽 용량만 해도 웬만한 웹 호스팅 업체의 최고 플랜 수준입니다.3

하지만 VPS가 모두에게 올바른 답은 아니라는 것

분명 가성비가 좋은 것은 알겠지만, 그렇다고 별다른 지식 없는 사람이 덜컥 VPS를 신청하게 되면 접속부터 헤매게 됩니다.

겨우겨우 접속해도 갓 설치된 Ubuntu4의 검은 콘솔이 너무나 당혹스럽습니다.

최소한 윈도우 설치는 여러 번 해보고, 컴퓨터와 소프트웨어 개념이 어느 정도 있는 사람이면 명령어5와 관련 프로그램을 익히는 것으로 꽤 능숙해질 수 있습니다. (자꾸 까먹어서 문제지만요)

그러니까 검은 화면에서 LAMP(Linux+Apache+MySQL/MariaDB+PHP) 또는 LEMP(Linux+nginX+MySQL/MariaDB+PHP) 구성은 할 줄 알아야 한다는 것이죠. 물론 이에 관한 강좌는 아주아주 많으니 따라하는 것만으로 꽤 손쉽게 완료할 수 있습니다.

다만 문제 해결에서 크게 갈리게 됩니다. 분명 퍼미션(권한) 문제가 여러분을 괴롭힐 것이고요.
그 외 문제 원인을 파악하는데 항상 어려움을 겪는다면, 서버를 운영하려고 했다가 배울 거리만 늘었다고 푸념하게 되실지도 모릅니다.

주요 업체 비교

사실 VPS 업체는 더 세상에 많고, 아래 업체들보다 더 견실한 곳도 더 많을 겁니다.

그러나 어디까지나 제 주관적인 경험을 적고자, 직접 개설해본 적이 있는 곳만 나열해봤습니다.

ConoHa

VPS Conoha
VPS라면 코노하!
모에한 미유키
모에한 미쿠모 코노하

conoha.jp
모에버전6

코노하는 일본의 GMO 인터넷 주식회사에서 운영하는 가상 서버 호스팅 서비스입니다. 모기업도 탄탄하다고 하고, 이곳은 뭐니뭐니해도 무제한 트래픽7이 특징입니다.

글로벌 영업도 활발해서, 한국어는 당연하다는 듯이 홈페이지와 관리 콘솔에서 지원하고 있습니다.

하지만 용도외 사용이거나, DDoS 공격의 표적이 되기라도 하면, 일방적으로 서비스가 해지되며, 이를 해결하기가 무척 까다롭습니다.

또한, 메일로 영문 문의가 가능한데, 전화로 급한 문제를 해결하려고 한다면, 일본어는 필수입니다.

100Mbps 회선만을 지원하여 다소 아쉬운 속도입니다. 그러나 핑, 서버 연산은 또 회선과 별개의 문제죠.

이상하게 다소 느립니다. 도쿄를 골라도요. 그리고 이게 널뛰기를 하는 걸 보니, 오버부킹8이 의심스러운 점도 있습니다.

이용 금액은 크레딧으로 충전하거나, 신용카드를 연결할 수 있습니다. (해외 결제)

서버를 꺼도 크레딧이 소모됩니다.

ConoHa 컨트롤 패널
ConoHa 컨트롤 패널
ConoHa Japan Plan
ConoHa Japan Plan

장점

  • CPU 혜자
  • 트래픽 혜자
  • 덕후를 위한 덕후 디자인 제공(별도 메뉴). 덕후 취향 아닌 분들을 위한 담담한 버전(기본값).

단점

  • 이상하게 느린 속도. 널뛰는 접속 속도. 높은 핑.
  • 상담, 문제해결이 어려움. 친절하지만 사무적인 상담원
  • 기능이 많은 것 같지만 기능이 적은 관리 콘솔. API를 이용하라지만 관련 안내는 전무함.
  • 리모트 뷰(원격 서버 그래픽 표시) 도구가 없음. SSH 죽으면 막막함.

솔직히 말해 덕후 취향 노리든 말든 느린 건 용서가 안 됨

Vultr

Vultr
Vultr

vultr.com

Vultr는 다른 VPS 업체에 비해 신생인 편에 속하나, 높은 업타임으로 높은 신뢰도를 기록하고 있는 업체입니다.

문제가 발생하면 군말없이 크레딧을 얹어주며 보상해주고, 평소에도 추천인 링크로, 많으면 페이백까지도 시켜주는 혜자 정책을 취하고 있습니다.

링크를 타고 가입하면 깎아주는 시절도 있었는데 지금 이 글을 올리는 시점에는 딱히 이벤트가 없는 것 같습니다. 사이트를 직접 확인해보세요.

관리 콘솔이 단순하면서 관리하기 편하고, 필수적인 요소를 모두 갖고 있습니다.

스냅샷 저장에 과금하지 않으며 별도로 제약 사항도 없습니다. 서버 인스턴스를 복제하는데 써먹을 수도 있고, 문제 생겼을 때 롤백하는 가장 편리한 방법입니다. 스냅샷 생성과 적용(복원)도 10분 내외로 끝날 정도로 빠릅니다.

10Gbps의 빠른 회선을 갖고 있으며, 전세계 여러곳에 서버를 갖고 있어 원하는 곳을 골라 만들면 유용합니다.

뉴저지에 만들면 무료로 블록 스토리지를 제공합니다. 블록 스토리지를 연결하면 추가 하드디스크를 연결한 것처럼 용량을 확장할 수 있고, 데이터를 안전하게 보관할 수 있습니다.

도쿄에 만들면 ConoHa 부럽지 않은데, 여기는 회선은 멀쩡한데 오버부킹이 또 심하게 의심됩니다. 회선의 상태는 좋다는 것을 테스트 사이트에서 직접 확인할 수 있죠.9

이용 금액은 크레딧으로 결제하거나, 해외 결제 카드를 연결 가능합니다.

서버를 꺼도 크레딧이 소모됩니다.

장점

  • 편리한 관리자 콘솔
  • 혜자스러운 크레딧 제공, 다운 시간 피해 보상
  • 웹상에서 서버 그래픽 콘솔 제공
  • 스냅샷 생성 가능

단점

  • 참을 수 있을 정도의 느린 속도
  • 도쿄 지역의 높은 사용률, 낮은 서버 준비율(오버부킹을 예상할 수 있는 Availability Low 표시가 있음)
    • 가까운 도쿄가 이러니 국내에서 활용하기엔 점점 부적합해지는 경향이 있습니다.
    • 태평양 건너 뉴저지랑 비슷할 때도 있으니 절레절레

Somagu

Somagu
Somagu

somagu.com

소마구는 미꾸라지를 운영하는 미꾸라지네트웍스에서 커스텀 VPS 상품을 2017년 하반기에 출시하면서 시작했습니다.

절제된 디자인과 절제된 기능인데 비해, NoVNC 등 여러 방법으로 서버를 제어할 수 있는 수단을 제공하고, 고성능으로 옵션을 올려도 높은 비용을 요구하지 않습니다. 부업의 자신감?

한국에서 서비스하려면 한국에 있다는 지리적 강점으로, 속도가 상당히 빠릅니다.

서버의 소재지를 공개하셨는데, 경남 함안군 칠서면 구포리 62-34(…)로 공장 내부 서버랙에서 돌아가고 있다고 합니다.

직접 관리하는 게 아니라 가족에게 위탁하고 상태를 원격으로 점검하시는 것으로 보이는데, 이 탓에 문제 대응이 느리며, 포럼에 문의를 남기면 답변에 약 3일 이상은 각오해야 합니다.

하지만 이에도 장점이 있는데, 관리 UI에 없는 기능이라도 부탁하면 관리자께서 편의를 봐주신다는 점이죠. 오히려 세심한 하부 부분에선 관리를 맡긴다는 면에서 급하지 않은 서비스에 더 적합할 수 있겠습니다. (OS 위의 일은 사용자가 알아서 해야겠지만요)

장점

  • 성능 대비 무척 저렴한 가격
  • 국내 서비스의 쾌적함 (KT망)
  • Toss로 크레딧 지불 가능

단점

  • 느린 문제/문의 대응
  • 불안한 업타임, 전력 문제
    • 부정기적인 일대 전력 점검으로 서버가 꺼지는 경우가 있음
    • 서버 일부에 문제가 있다고 하셨으며, 교체 작업으로 인해 2017년 12월 기준 일시적으로 고사양 신청이 중단된 것으로 보임
  • 관리 도구의 기능 부재
    • 스냅샷 생성 기능이 별도로 없음
    • 관리 콘솔에선 컴퓨터 켜고 끄기, 원격 접속 정보 제공이 거의 대부분의 기능
  • 스위치 기반의 연결인데 포트 점유가 있는 듯
    • 같은 외부 포트를 여러 사용자가 같이 쓸 수 없는 것으로 보임
    • 20개로 제공된 포트 내에서 웹 UI를 통해 관리해야 함
    • 80 / 443 포트와 같은 HTTP에 대해서는 가상 호스트 방식으로 매핑해줌 (웹서버 동작에 이상은 없음)
    • 모든 원격 연결이 10.0.0.1 같은 내부 스위치 IP로 넘어옴. 방문자 IP 구분 불가. (X-Forwarded라도 ㅠㅠ)

스마일서브 (IwinV)

IwinV
IwinV

iwinv.kr

2002년부터 설립되어 오랫동안 발전시켜온 노하우를 갖고 있는 회사인데, 2014년 적자 업체 아이비호스트도 인수하는 등 적극적인 사업 확장 중입니다. VPS 분야는 iwinv에서 별도로 관리중입니다.

이 업체의 강점은 다양한 옵션, 저렴한 가격입니다.

장점

  • 가상코어, 리얼코어, 단독서버로 3단계로 나눈 상세 스펙 선택 가능
    • 가상코어란 CPU Core를 가상으로 다시 쪼갠 것으로, 다수 사용자에게 제공하기 위한 방법입니다. 타 사용자의 Core 사용량에 따라 크게 널뛰게 됩니다.
    • 리얼코어 사용시 CPU가 가상화로 인한 감쇠(10% 이내라고 주장)만 있고, 타 사용자의 간섭을 크게 줄일 수 있습니다.10
    • 단독서버가 당연히 제일 비싸지만, 그래도 타사보다 많이 저렴한 편
  • 포트 개방, 리소스 현황 파악 및 설정 상태 도달시 문자, 텔레그램, 이메일 통보 가능
    • 단, 문자는 문자 발송비에 대해 선충전후발송이므로, 텔레그램을 사용하는 편이 좋음. 자세한 설명이 실려 있음.
  • 기본 웹 방화벽 제공. OS도 방화벽 제공.
  • 웹상에서 서버 그래픽 콘솔 제공.
  • 스냅샷 생성 가능. 무료 생성 한도는 신청 인스턴스(서버) 용량의 2배까지만.
  • 신용/체크카드 후불형 결제
  • 블로터 등 유명 사이트들과 같은 IDC 센터 사용 (문제 발생 요인이 적음)

단점

  • 추가로 싸게 만들 프로모션은 딱히 눈에 띄지 않음
  • 부족한 결제 옵션

결론

VPS라는 것이 저렴해지고 가시화된지 오래되지 않아서 정보를 모으기 쉽지 않습니다.

그러나 리눅스에 보다 익숙해지고, 대형 서버에 의존하지 않는 자신만의 보안 대책을 강구하기 위해서라도 피할 수 없는 흐름인 것 같습니다.

하지만 어디까지나 본인에게 맞는지 따져보고서 결정할 일이겠죠. 여럿이 모여서 하나의 VPS를 신청해보는 것도, 사양이 허락한다면 꽤 유연한 사용 방법이지 않을까 생각합니다.

Galaxy Note 7

[번역글]aptX vs. aptX HD: 차이점에 대해서

3.5mm 헤드폰 플러그가 멸종 위기에 처한 지금, aptX HD가 변화를 만들어 낼 수 있습니다.

블루투스에 대해 읽어보셨다면, 수많은 글자와 숫자와 비밀스런 스펙을 마주하셨을 겁니다. 이들 중 가장 최신은 aptX HD 인데, 이상한 이름 뒤에 HD가 붙었습니다. HD가 “고선명”이라는 건 다들 아실텐데, 그러면 aptX는 또 뭘까요? aptX(고선명 사양을 포함해서)가 aptX HD랑 뭐가 다를까요?

이런 질문을 하는 사람은 여러분만이 아닙니다. 같이 알아보도록 합시다.

aptX가 무엇입니까?

hbs910
hbs910

aptX는 352kbps에서 4:1 압축률로 16비트/44.1kHz 오디오를 전송할 수 있는 블루투스 오디오 코덱입니다.

그다지 도움이 되진 않지만, 이게 여러분이 궁금해하는 aptX의 사양입니다. 이는 (여러분의 폰이나 컴퓨터, A/V 리시버 또는 그 외 블루투스 오디오를 전송할 수 있는) 장치가 오디오를 “CD 수준” 음질로 전송한다는 것입니다. 원본 소리가 CD 음질 이상이면, 소리가 훨씬 좋게 들립니다.

본래의 aptX 코덱은 CD 수준의 음질을 약속했고, 거의 그에 도달했습니다.

CD 음질과 “CD 수준” 음질의 차이에 주목하세요. 이는 압축때문에 생긴 표현입니다. aptX는 다른 블루투스 오디오 코덱처럼, 오디오를 보내고 장치(여러분의 헤드폰이나 다른 스피커)에서 받는 재생 과정에 압축과 압축 해제를 사용합니다. 데이터를 압축하고 전송해야 하는 이유가 있는데, 그것은 바로 블루투스가 스테레오 오디오 전송을 하기에 충분히 빠르지 않기 때문이란 점입니다. aptX 코덱은 소리 지연을 줄이는데 중점을 두었는데, 지연이란 소리를 보낸 후 들을 때까지 걸리는 시간을 말합니다.

음악을 듣는다면, 지연은 크게 문제가 되지 않습니다. 폰을 쓰면서 헤드폰에 상당항 딜레이가 있더라도 눈치채지 못할 수 있습니다. 하지만 동영상을 본다면 확실히 얘기가 달라집니다. 영상이 약간 구닥다리 더빙처럼 느껴지고 배우들의 립싱크가 맞질 않는 걸 쉽게 느낄 수 있습니다.

“[번역글]aptX vs. aptX HD: 차이점에 대해서” 더보기

PocoTube on Omnia II

PocoTube (2010)

PocoTube on Omnia II
Omnia2 PocoTube App

PocoTube 는 오프라인 상태에서, 선택한 노선에서 전철의 현위치를 알려주는 Windows Mobile 앱입니다.

개발 동기

PDA폰에서 스마트폰으로 넘어가는 과도기에, 여전히 지하철 앱은 단순히 역간 소요 시간을 더해주는 선에서 그 역할이 머무르고 있었습니다. 서울시에 지하철 9호선이 들어오면서 지하철 급행이라는 개념이 추가되자, 나중에 오는 열차가 어느 역부터 더 빨리 가게 되는지, 보다 더 고도화된 정보 제공이 필요하게 되었습니다. 열차가 언제 오고, 어떤 추월 관계를 갖는지, 언제 도착하는지 알려주는데 특화된 앱을 만들기로 결정했습니다.

개발 언어 및 도구

  • C#
  • Microsoft Visual Studio 2008 (Dreamspark)
  • .NET Compact Framework 3.5

“PocoTube (2010)” 더보기

excercise1

짧게 풀어보는 Java 급 테스트

가뜩이나 환절기에 콧물 시큰시큰이라 머리가 띵한데 Java 실력 체크를 위한 시험을 보게 되었습니다.

다들 풀 수 있는 수준으로 나온다고 하지만, 모두에게 그러리라는 법은 없기 때문에, 넉넉한 시간에도 불구하고 끙끙대시는 분들이 많았습니다.

문제는 총 8문제였습니다.

Java 문제 1. 일의 자리를 1로 바꾸는 코드를 작성하라.

문제 1

public class Exercise1 {

	public static void main(String[] args) {
		int num = 333;
		int num2 = (int)Math.round((double)(Math.floor((float)num*0.1f)))*10+1;
		System.out.println(num2);
	}

}

사실 num / 10 * 10이 훨씬 쉽긴 합니다만, 나름 이유가 있어서라고 생각했는데… 풀고나니 참 쓸데 없는 짓을 했구나 싶은 부분입니다.

어떤 분은 String으로 바꾸고 치환하고 Integer.parseInt() 했다고 하시네요. 아… 제가 머리가 굳었나봅니다. 세상은 참신한 방법이 널리고 널렸어요.

“짧게 풀어보는 Java 급 테스트” 더보기