콘텐츠로 이동

LINE 날씨 챗봇 서버 구축기 (CentOS 7 + nginx + Let's Encrypt)

LINE Messaging API로 서울 날씨를 알려 주는 Node.js 챗봇을 만들었다. 이 글은 주로 리눅스 서버 구축 과정을 정리한다.

  • 개발 기간: 2018-12-01 ~ 2018-12-02
  • 목표: nginx와 SSL을 직접 구축하고, Node.js와 Express 구성을 익힌다.
  • 환경: CentOS 7(NAVER CLOUD PLATFORM), Node.js, Express
  • 도구: Visual Studio, FileZilla, PuTTY, Git Bash

날씨 챗봇 실행 화면

채널과 개발자 계정 생성, 봇 등록은 LINE Developers 가이드에 나와 있다. 웹훅 URL은 반드시 HTTPS여야 한다. 그래서 도메인과 인증서가 필요하다.

  • SSL 인증서를 받으려면 도메인이 있어야 한다. 가장 싼 도메인을 샀는데, 첫해만 싸고 그다음 해부터는 10~20배 가격이 붙으니 갱신 비용을 미리 확인한다.
  • NAVER CLOUD PLATFORM에서 서버를 만들 때는 ACG(접근 제어 그룹) 규칙에 80 포트가 기본으로 열려 있지 않아서 직접 추가해야 한다.
  • 도메인 관리 도구의 DNS 설정에 서버의 공인 IP를 A 레코드로 넣어 연결한다.

CentOS 7의 방화벽 데몬은 firewalld이고, iptables 명령 대신 firewall-cmd를 쓴다.

터미널 창
yum install firewalld
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

외부로 패킷을 내보내는 NAT 구성이 없어서 마스커레이딩은 켜지 않았다. 필요하면 firewall-cmd --permanent --add-masquerade로 켠다.

Node.js 앱은 8080(HTTP)과 4443(HTTPS)에서 띄우고, 앞단의 nginx가 80·443으로 받은 요청을 앱으로 넘기게 했다.

  1. 저장소 파일 /etc/yum.repos.d/nginx.repo를 만든다.

    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/7/$basearch/
    gpgcheck=0
    enabled=1
  2. 설치하고 서비스를 켠다.

    터미널 창
    sudo yum install -y nginx
    systemctl start nginx
    systemctl enable nginx
  3. /etc/nginx/conf.d/에 서버 설정 파일(bot.conf)을 만들어 80 포트와 앱을 연결한다.

conf.d 안의 설정 파일은 이름 순서로 읽힌다. default.conf보다 먼저 적용하려면 그보다 앞서는 이름(a~c로 시작)으로 만든다.

무료 인증서인 Let’s Encrypt를 수동 방식으로 발급했다.

터미널 창
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help # 의존 패키지 설치
./letsencrypt-auto certonly --manual

수동 발급에는 도메인 소유를 확인하는 URL 인증 단계가 있다. 요청한 경로의 파일을 nginx나 Express에서 응답하게 하면 된다. 발급이 끝나면 /etc/letsencrypt/live/<도메인>/에 인증서 파일이 생긴다.

Express에 직접 붙일 수도 있지만, 이미 nginx를 쓰고 있어서 nginx에서 TLS를 끝냈다. 설정은 Mozilla SSL Configuration Generator로 만들고, 아래 항목에 발급받은 파일 경로를 넣었다.

  • ssl_certificate
  • ssl_certificate_key
  • ssl_trusted_certificate
  • ssl_dhparam

ssl_dhparam용 2048비트 키를 만들 때는 키를 둘 디렉터리에서 실행하거나 -out으로 경로를 지정한다.

Let’s Encrypt 인증서의 유효 기간은 90일이다. 기간이 지나면 HTTPS가 동작하지 않으므로 갱신해야 한다.

터미널 창
./certbot-auto renew

갱신이 성공하면 /etc/letsencrypt/live/<도메인>/의 심볼릭 링크가 새 인증서를 가리킨다.

  • Express로 HTTP·HTTPS를 받고, 서버 구동(app.js)과 웹훅 응답(reply.js)으로 파일을 나눴다.
  • 외부 API 호출에는 request 모듈을 썼다.
  • 국내 날씨 API는 키 발급 과정이 길어서 OpenWeatherMap을 썼다. 응답이 영어지만 필요한 필드가 적어 서버에서 직접 파싱했다.
  • CentOS 7에 Node.js와 npm을 설치한 뒤 npm install이 실패했다. yum install openssl로 OpenSSL을 설치해 해결했다.