AWS EC2에 code-server 설치하고 커스텀 도메인 ssl 배포까지

jakeshin·2020년 6월 2일
1
post-thumbnail

여기서도 읽을 수 있습니다! Notion

code-server는 웹에서 VS-Code를 쓸 수 있도록 해주는 서비스다. 전역 후 아이패드로 코딩할 생각에 행복회로를 돌리던 나는 미리 구현해놓기로 했다. 어차피 사지방에서 코딩할 때도 필요해서.. 그런데 자료가 상당히 부족하고, nginxproxy에 관한 지식도 부족해 많이 헤맸다. 이 과정을 기록해둬 나중에 다시 환경을 구축해야 할 때 참고하고자 한다.

EC2 설정

AWS EC2에 올릴 예정이니, 인스턴스 생성을 가장 먼저 해야한다.

보안그룹에서 꼭 허용해줘야 하는 포트들

  1. 80: HTTP
  2. 22: SSH 접속
  3. 443: ssl 적용

나머지 포트들은 각자 필요하면 추가하기~

이대로 인스턴스를 만들어주기만 하면 AWS자체에서 할 설정은 없다. 이후 과정들은 ssh로 인스턴스에 접속한 상태에서 진행한다.

ssh -i ubuntu@<ec2 public domain>

code-server 설치

공식문서에서 제공하는 설치 명령어를 사용하면 된다. 이 경우 서비스가 systemctl --user단에 설정된다.

curl -fsSL https://code-server.dev/install.sh | sh

그 다음 systemctl --usercode-server를 활성화해야 한다. 이 명령어는 설치 명령어에서 마지막에 하라고 알려준다.

systemctl --user enable --now code-server

nginx를 활용한 proxy redirection 설정

code-serverlocalhost로만 서비스를 제공한다. 이를 외부로 보내줄 proxy가 필요하다. nginx로 이를 구현해보자. 먼저 nginx를 설치한다.

sudo apt install nginx

이후 code-server가 사용할 .conf파일을 만들어준다. 우린 certbot을 통해 ssl을 설정할거고, 테스트도 할 겸 http 연결로 만들어주자.

sudo vim /etc/nginx/sites-available/code-server.conf

server {
	listen 80;
	listen [::]:80;
	server_name <instance ip>;
	location / {
		proxy_pass http://127.0.0.1:8080/;           
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection upgrade;
		proxy_set_header Accept-Encoding gzip;
	}
}

sites-enable에 링크를 생성해준다. 이후 수정할 때는 sites-available의 파일만 수정해주면 된다!

sudo ln -s /etc/nginx/sites-available/code-server.conf /etc/nginx/sites-enabled/code-server.conf

이후 nginx문법을 확인하고 서비스를 재시작해준다. 이 때는 그냥 systemctl이다.

sudo nginx -t
sudo systemctl restart nginx

여기까지 하면 인스턴스 ip만 주소창에 치면 code-server접속이 가능하다. 하지만 code-server에선 안전하지 않은 도메인으로 접속하면 일부 기능을 제한시킨다. ssl을 적용시켜보자.

ssl 적용

우선, 도메인을 하나 구매하고, A 레코드에 인스턴스 주소를 추가해둔다. (서브도메인은 마음대로~) 이렇게 한 상태에서 진행하는 게 마음이 편하다.

certbot을 통한 let's encrypt 설정

  1. certbot 설정
    apt-get에 certbot저장소 추가.
    sudo add-apt-repository ppa:certbot/certbot
패키지 목록을 업데이트, `certbot`설치
    sudo apt-get update
    sudo apt-get install python-certbot-nginx
간혹 업데이트와 업그레이드가 되지 않는 경우 (최신버전 권장)
    sudo add-apt-repository ppa:certbot/certbot
  1. nginx 세팅
    sudo vim /etc/nginx/sites-available/code-server.conf
서버 블록 파일 안에 `server_name`을 설정하고자 하는 도메인 이름으로 변경
    server {
    	listen 80;
    	listen [::]:80;
    	server_name <your domain>;
    	location / {
    		proxy_pass http://127.0.0.1:8080/;           
    		proxy_set_header Upgrade $http_upgrade;
    		proxy_set_header Connection upgrade;
    		proxy_set_header Accept-Encoding gzip;
    	}
    }
문법검사 + 재시작
    sudo nginx -t
    sudo systemctl restart nginx
  1. ssl 인증 획득 - 인증서 만료 알림을 받는 메일과 https 리다이렉션 옵션 선택
    sudo certbot --nginx -d <your domain>

(매우 중요!!!) 중단시키지 않고 code-server 돌리기

위와 같이 설정하면, ec2ssh연결을 끊는 순간 웹페이지가 다음과 같은 메시지를 띄우며 접속이 안 될 것이다.

502 Bad Gateway nginx/1.14.0 (Ubuntu)

이는 다음 명령으로 해결할 수 있다.

loginctl enable-linger ubuntu

여기까지 따라오면 설정은 끝이다. 이제 로컬에서 사용하는 vscode의 설정을 settings-sync로 옮겨와 작업환경을 구성하고, 터미널을 꾸미면 된다! 이 뒤는 왜 저 명령을 사용하는지에 대한 내용으로, 궁금하지 않다면 읽지 않아도 된다 ~~사실 뒷내용은 이 부분에서 삽질을 가장 오래 해서 적는 푸념글에 가깝다~~

왜 저 명령을 써야 하나요?

ssh 연결에 사용하는 22번 포트 단절을 nginx가 비정상적 종료라 생각하고 서버를 내려버린다라는 가정을 세우고, 설정 문제일거라 생각하고 뭐가 문제인지 8시간이 넘게 구글링했는데, 시원한 해결방법을 발견할 수 없었다. ~~구글에는 나처럼 멍청한 사람이 없었기 때문이다...~~ 그리고 나중에 확인해보니, 심지어 nginx 자체는 내려가지 않았다(인스턴스 ip로 접속해보니 success가 출력된다).

결국 새로운 인스턴스를 만들고 공식 가이드와 타 커뮤니티 가이드들, 그리고 위 글을 참고하여 차근차근 다시 해보고 있었는데, 한 가지 의문이 들었다.

왜 타 커뮤니티에선 전역 systemd를 사용하는데 공식 가이드만 systemd -user레벨을 사용하는 걸까?

실제로 위 스크립트를 실행하면 전역 systemd로는 설정이 안되고, user레벨에서만 가능하다 (애초에 파일 생성을 user레벨에서 설정하는 경로로 넣어주니까..) 왜 그런지 궁금해서 systemd -user에 대해 검색해보기 시작했다. 그리고 충격적인 사실을 알게 되었다.

PAM 모듈은 사용자가 로그인을 하게 되면 자동으로 systemd –user 명령을 실행해준다. 그리고 로그아웃을 하게되면 systemd –user 로 실행된 프로세스는 종료된다.

그렇다, 연결이 끊어진 이유는 ssh와 관련된게 아니라, 로그아웃이 됐기 때문이다!

크게 두 가지 방법으로 이를 해결할 수 있다.

  1. 전역 systemd로 설정을 옮긴다.
  2. loginctl enable-lingeruser manager가 로그아웃시에도 끊어지지 않게 한다.

나는 이미 도메인에 ssl까지 세팅을 해놨고, 터미널 세팅도 하다가 이 이슈를 발견해서 2번으로 해결했다. 파일들을 통채로 옮기다 무슨 일이 벌어질지 걱정이 됐기 때문이다 (더 이상 구글링을 하고싶지 않기도 했다)

어떤 선택이 보안적 측면에서, 또는 시스템 측면에서 유리할지는 모르겠다. 다만 어차피 유저별로 systemd를 나눠둘 이유도 없으며, 로그아웃시에도 켜져있어야 하니 1이 더 근본적인 해결책에 가깝다 생각한다. 이렇게 할 경우 간편한 공식 설치 명령어보단 직접 [Unit]을 작성해 구성하는 편이 더 자연스럽다 (설치를 다 해두고 옮기는건 그림이 뭔가 웃기잖아,, 처음부터 맞는 자리에 설치해야지)

결과

code-server login

REVIEW

어려워보이는 ssl 설정은 쉽게 끝냈는데, 문제의 원인을 빠르게 찾아내지 못했고, 리눅스 systemd에 무지해서 시간이 너무 오래 끌렸다. 문제가 생겼을 때 그 현상 자체만 생각하며 검색하며 문제를 해결한 다른 누군가를 찾는것보다, 내가 해온 과정을 처음부터 되짚어가며 놓친게 없는지 하나하나 확인해보는게 더 생산적인 문제해결방식이라는 생각을 하게 됐다.

참고 (고마운 분들)

  1. Coding on iPad! Install code-server on AWS EC2 and running VSCode on iPad
  2. [Nginx] Let's Encrypt를 통해 Nginx에서 무료로 https 설정하기(Ubuntu 14.04)
  3. Systemd -User 사용하기
profile
새싹 개발자🌱

1개의 댓글

comment-user-thumbnail
2021년 3월 9일

유용한 정보 정말 감사드립니다! 저도 EC2를 사용해서 원격으로 개발을 하려고 알아보다가 이 글을 보고 도움을 많이 받았습니다. 그런데 EC2 EBS-backed instance의 경우 stop을 시킨 후 다시 start 했을 때 public IPv4가 변경되어 기존에 설정했던 ip 와 도메인으로 접속이 안 되는 문제가 발생했는데, 혹시 JaKe님은 이 문제를 해결하셨나요?

답글 달기