백엔드 개발자 로드맵 따라가기 9. 웹 보안 - Oracle VM+VScode+NGINX+TLS(HTTPS) 구성하기

박성수·2020년 11월 24일
1

1. 프로토콜

복수의 컴퓨터 사이나 단말기 사이에서 통신을 원활하게 하기 위해 필요한 통신 규약이라고 한다.

네트워크의 규모가 증가되고 네트워크를 이용한 정보 전송 수요가 다양화되면서 프로토콜의 기능이 분화되고 복잡해질수 밖에 없다.

이러한 환경적인 요구를 만족하기 위해 프로토콜 계층화 개념이 나타나게 되었다.

위 7계층 프로토콜을 TCP/IP 4계층으로 웹서비스에 맞게 단순화 시킨 모델의 구조와 동작은 아래와 같다.

2. HTTP 와 HTTPS 차이

2-1. HTTP (Hypertext Transfer Protocol)

서로 다른 시스템들 사이에서 통신을 주고 받게 해주는 가장 기초적인 프로토콜이다.

2-2. HTTPS (Hypertext Transfer Protocol Secure)

기존 HTTP는 데이터 전송간에 정보가 암호화 되지 않는 문제를 가지고 있었고 이 문제를 해결하기 위해 나온 프로토콜이 HTTPS 이다.

HTTPS는 TLS를 이용하여 전송 데이터를 암호화한 프로토콜을 의미한다.

초기 SSL과 TLS를 혼용했으나, 명확히 말하면 현재는 TLS를 사용하고 있다.

SSL은 넷스케이프가 개발한 것이고 TLS는 IETF(Internet Engineering Task Force, 국제 인터넷 표준화 기구) 표준이다.

HTTPS는 크게 3가지 방식으로 데이터 안전성을 보장한다.

2-2-1. 기밀성

인증되지 않은 대상이 정보를 읽지 못하도록 하는 것

2-2-2. 무결성

데이터가 변조되지 않았다는 보장

2-2-3. 인증

상대방의 신원을 알기위해 제3자 인증 기관으로부터 발급받은 인증서를 통한 신원 파악

2-3. 무조건 HTTPS가 좋은가?

당연히 가능하다면 HTTPS가 좋다. 하지만 넷상의 모든 데이터가 반드시 암호화가 필요한 것은 아니다. 단순 검색 등의 정보 전달인 경우 HTTP만으로도 충분하다.

HTTPS를 구성하려면 기타 비용이 발생할 수 있다.

<참고>
https://webactually.com/2018/11/16/http%EC%97%90%EC%84%9C-https%EB%A1%9C-%EC%A0%84%ED%99%98%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EC%99%84%EB%B2%BD-%EA%B0%80%EC%9D%B4%EB%93%9C/

3. Oracle VM+VScode+NGINX+TLS(HTTPS) 구성하기

이제 VM 서버 위에 VScode를 구성하고 NGINX를 프록시 서버로 활용할 것이다. 거기에 NGINX 가 플러그인으로 제공하는 Certbot을 활용해서 HTTPS 적용까지 해보자.

구성이 완료되고 나서의 대략적인 전체 흐름을 그려보면 아래와 같다.

필자의 VM 서버의 OS는 CentOS8 이다.

3-1. VM 환경 구성

VM 서버는 오라클에서 제공하는 평생 무료 클라우드를 사용했다.

https://www.oracle.com/kr/cloud/free/

관련해서 잘 정리된 포스팅이 많으므로 참고해서 이용하면 좋을 듯 하다.

3-2. 방화벽 오픈

블로그대로 잘 따라 했는데 왜 접속이 안되지? 했을 때, 대부분의 문제는 방화벽이다.

그만큼 중요하기 때문에 잘 확인하자.

# 방화벽 상태 확인
sudo systemctl status firewalld

# 방화벽 포트 추가
$ firewall-cmd --permanent --zone=public --add-port=22-24/tcp
$ firewall-cmd --permanent --zone=public --add-port=80/tcp
$ firewall-cmd --permanent --zone=public --add-port=443/tcp

# 방화벽 서비스 추가
$ sudo firewall-cmd --permanent --zone=public --add-service=ssh
$ sudo firewall-cmd --permanent --zone=public --add-service=http
$ sudo firewall-cmd --permanent --zone=public --add-service=https

# 방화벽 포트 및 서비스 추가 확인
$ sudo firewall-cmd --permanent --zone=public --list-services

# iptables 체인 추가
$ sudo iptables -I INPUT 5 -i ens3 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
$ sudo iptables -I INPUT 5 -i ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$ sudo iptables -I INPUT 5 -i ens3 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT

# iptables 체인 추가 확인
$ sudo iptables -L

# 방화벽 재기동
$ sudo firewall-cmd --reload

오라클 VM 사용시 방화벽을 꺼버리거나 iptables 체인을 초기화 시키는 경우가 있는데 절대 하지 말아야 할 행동이다. 또한 VM의 경우 서버 자체의 방뿐만 아니라 개인 구성 환경(클라우드)에 따라 포트포워딩이 필요하다.

3-3. Domain 주소 생성

만약 개인 도메인 서버가 있다면 이 단계는 패스해도 된다.

Domain 서버가 없는 경우 무료로 간단히 서버를 제공해주는 사이트가 있다.

https://www.freenom.com/en/index.html?lang=en

이것 역시 잘 정리된 사이트들이 많으니 참고해서 생성하자.

도메인 서버를 만들고
Services > My Domains 메뉴에서 자신이 만든 도메인 주소를 확인할 수 있을 것이다.

또한 해당 도메인 주소가 바라봐야하는 서버 주소를 아래처럼 Target에 기입하고 저장하자.

여기서 끝을 내면 안되고 아래처럼 확인을 해야 한다.

# cmd 창에서 nslookup -type=A <도메인>
ex) nslookup -type=A www.test.ga

이 때, 아래와 같이 권한 없는 응답에서 자신의 도메인 서버가 가리키는 IP 주소가 명확히 나와야 하는데, freenom 서버에서 설정 후 몇 분 정도 기다려야 될 때도 있다.

3-4. NGINX 구성

$ sudo yum install -y yum-utils

$ sudo vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

$ sudo yum install -y nginx

$ sudo systemctl start nginx
$ sudo systemctl enable nginx
$ sudo systemctl status nginx

NGINX 기동 후 IP주소:80 으로 들어가면 아래와 같은 디폴트 화면이 보일 것이다. 만약 여기서부터 접속도 안되고 막힌다면 다음 step을 밟아도 소용 없으니 방화벽과 서버 상태를 먼저 확인하자.

3-5. VScode 구성

$ mkdir ~/code-server
$ cd ~/code-server

$ curl -LO https://github.com/cdr/code-server/releases/download/3.2.0/code-server-3.2.0-linux-x86_64.tar.gz

$ tar -xzvf code-server-3.2.0-linux-x86_64.tar.gz

$ sudo cp -r code-server-3.2.0-linux-x86_64 /usr/lib/code-server

$ sudo ln -s /usr/lib/code-server/code-server /usr/bin/code-server

$ sudo mkdir /var/lib/code-server

$ sudo vi /usr/lib/systemd/system/code-server.service
[Unit]
Description=code-server
After=nginx.service

[Service]
Type=simple
Environment=PASSWORD=<your_password> # 로그인시 사용
ExecStart=/usr/bin/code-server --bind-addr 0.0.0.0:8443 --user-data-dir /var/lib/code-server --auth password
Restart=always

[Install]
WantedBy=multi-user.target

$ sudo systemctl start code-server
$ sudo systemctl status code-server
$ sudo systemctl enable code-server

3-6. NGINX 도메인 서버 등록 및 VScode로의 리디렉션

$ sudo vi /etc/nginx/conf.d/code-server.conf
server {
    listen 80;
    listen [::]:80;

    server_name <본인의 도메인 주소>;

    location / {
        proxy_pass http://localhost:8443<리디렉션할 port>/;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Accept-Encoding gzip;
    }
}

$ sudo nginx -t
$ sudo systemctl restart nginx
$ sudo setsebool httpd_can_network_connect 1 -P

여기까지 하고 http://<도메인주소> 로 접속을 하면 VScode 웹화면이 뜨고 사용할 수 있지만 http 구성이므로 보안에 취약하고 VScode 내에서도 여러 기능을 사용할 수 없다.

3-7. Certbot - TLS(HTTPS) 구성

진행하기 전에 HTTPS가 방화벽 서비스에 등록되어 있는지 먼저 확인하자.

아래 과정 중 대화식 설치기 때문에 뭘 계속 물어보는데 다 yes 하자.

설치가 끝나면 위 NGINX에서 리디렉션 80 -> 8443 을 자동으로 443(HTTPS) -> 8443 으로 설정도 수정해준다.

$ sudo yum install -y certbot python3-certbot-nginx

$ sudo certbot --nginx -d <도메인 주소>

# certkey를 지정 주기마다 갱신
$ sudo crontab -e
15 3 * * * /usr/bin/certbot renew --quiet

구성이 완료되면 아래 url로 https 구성을 테스트 해볼 수 있다.
https://www.ssllabs.com/ssltest/analyze.html?d=<https 를 구성한 도메인명>

위의 테스트 결과가 정상이라면 이제 https://<도메인 주소>로 접속해보자.

<참고 자료>
https://www.digitalocean.com/community/tutorials/how-to-set-up-the-code-server-cloud-ide-platform-on-centos-7#step-2-%E2%80%94-exposing-code-server-at-your-domain

profile
Java 백엔드 개발자입니다. 제가 생각하는 개발자로서 가져야하는 업무적인 기본 소양과 현업에서 가지는 고민들을 같이 공유하고 소통하려고 합니다.

0개의 댓글