티스토리 뷰
오늘은 Nginx와 daphne을 이용한 django channels(web socket)에 보안 연결을 적용하는 방법을 소개합니다.
위 목적을 이루기 위해서는 크게 2가지 방법이 있습니다.
첫 번째 방법은 Nginx에 직접 ssl 보안 설정을 하는 것이고,
두 번쨰 방법은 daphne의 -e 옵션을 사용해 소켓 연결에 ssl 보안을 설정하는 방법입니다.
두 가지 방식의 차이점
첫 번째 방식은 web server 단계에서, 두 번째 방식은 django Application 단계에서 보안 인증서를 적용합니다.
만약 Nginx와 daphne을 이용해 web socket을 배포하신다면 첫 번째 방식을 추천드립니다.
첫 번째 방식을 사용하시면 모든 https(https://...), wss(wss://...) 연결을 하나의 보안 인증서로 관리할 수 있지만, 두번째 방식은 오직 daphne으로 돌아가는 application에만 보안 인증서가 적용되어 여러개의 보안 인증서가 필요하게 될 수 있습니다.
1. Nginx 설정에 보안 인증서 적용하기
보안 인증서 적용
보안 인증서를 만들어줍시다. 저는 Certbot을 이용해 보안 인증서를 만들었어요.
필요한 정보 (ex: 도메인 등)를 입력합니다.
아마 바로 인증서가 위치한 경로를 알려줄텐데 잘 복사해 둡시다!
필요한 패키지를 깔고 생성된 인증서를 /usr/bin/cerbot (Certbot의 실행 파일이 위치하는 경로)에 연결합니다.
apt install snapd
snap install core
snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot certonly --nginx
Nginx 설정하기
ssl_certificate 부분에 아까 받아온 fullchain.pem 경로를 입력해주세요.
ssl_certificate_key 부분에 함께 받은 privkey.pem 경로를 입력해주세요.
*추가 설정
1. 하나의 백엔드 서버만 사용하였어요. 로드 밸런싱을 사용하지 않았습니다. 로드 밸런싱 사용 시 upstream 블록에 여러 서버를 추가해주세요.
2. http의 기본 포트인 80으로 들어오는 요청은 모두 https로 리다이렉트 하였습니다.
3. https의 기본 포트인 443으로 들어오는 요청을 처리합니다.
4. 로그 파일의 경로를 설정해주었습니다. access_log, error_log
5. 정적 파일인 .static_root와 media 경로를 설정해주었습니다.
6. 일반적인 요청과 /ws로 들어오는 websocket 요청을 분리하여 처리하였으며 필요한 헤더 설정을 추가해주었습니다.
upstream app_server {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
server_name example.com;
access_log /var/log/nginx/example.com_access.log combined;
error_log /var/log/nginx/example.com_error.log error;
ssl_certificate /{example_ssl_certificate_route}/fullchain.pem;
ssl_certificate_key /{example_ssl_certificate_key_route}/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
location /static/ {
alias /.../.static_root/;
}
location /media {
alias /.../media/;
}
location / {
proxy_pass http://app_server;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ws {
proxy_pass http://app_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
daphne 설정하기
저는 systemd 서비스를 이용해 daphne을 구동했습니다. daphne.service 파일입니다.
*추가 설정
재시작 여부, 명령어 정의 등을 해줍니다.
ExecStart=/bin/bash -c 'source {가상환경 active 경로} && daphne -b 0.0.0.0 Project.routing(or asgi):application {추가 옵션} --access-log /var/log/daphne/daphne.log' : daphne을 실행시키기 위한 가상환경을 활성화 해주고, daphne을 구동시킵니다. 외부 접근 활성화를 위해 0.0.0.0으로 바인딩했으며 기본 포트는 8000입니다.
ExecReload=/bin/kill -s HUP $MAINPID : 재시작 명령어입니다.
ExecStop=/bin/kill -s TERM $MAINPID : 중지 명령어입니다.
Restart=on-abort : daphne 서비스가 중단될 경우 자동으로 다시 시작하도록 합니다.
PrivateTmp=true : 서비스 실행 중 생성되는 파일은 프로세스가 종료될 때 삭제됩니다.
WantedBy=multi-user.target : 이 서비스가 다른 서비스와 함께 시작될 때 실행되는 순서를 결정합니다.
[Unit]
Description=daphne daemon
[Service]
User=DevelopmentAccount
Group=www-data
WorkingDirectory={프로젝트 경로}
Environment="PATH={가상환경 경로}"
ExecStart=/bin/bash -c 'source {가상환경 active 경로} && daphne -b 0.0.0.0 Project.routing(or asgi):application {추가 옵션} --access-log /var/log/daphne/daphne.log'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
Restart=on-abort
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Nginx & daphne 구동하기
이렇게 설정 후 아래 명령어를 실행해주면 정상적으로 작동합니다.
sudo systemctl daemon-reload
sudo systemctl enable daphne
sudo systemctl stop nginx
sudo systemctl stop daphne
sudo systemctl start daphne
sudo systemctl start nginx
sudo systemctl status nginx
sudo systemctl status daphne
위 명령어로 활성화 여부를 확인할 수 있습니다.
2. daphne (django application)에 보안 인증서 적용하기
1번과 달리 Nginx의 보안 인증서를 제거하고 daphne 설정만 변경하면 됩니다.
아까와 달리 -e 옵션을 사용해 application 단계에서 보안 연결을 사용합니다.
[Unit]
Description=daphne daemon
[Service]
User=DevelopmentAccount
Group=www-data
WorkingDirectory={프로젝트 경로}
Environment="PATH={가상환경 경로}"
ExecStart=/bin/bash -c 'source {가상환경 active 경로} && daphne -b 0.0.0.0 -e ssl:8443:privateKey={인증서 경로}/privkey.pem:certKey={인증서 경로}/fullchain.pem Project.routing(or asgi):application {추가설정} --access-log /var/log/daphne/daphne.log'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
Restart=on-abort
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- Total
- Today
- Yesterday
- 컨트롤타임
- 아나콘다
- 바닐라 js
- localstorage
- Codeup
- 1253
- SMTP
- django
- 바닐라 javascript
- 문제풀이
- 사칙연산
- 1251
- 코드설명
- JavaScript
- 1255
- 2022.02.05
- 크롤링
- 티처블 머신
- 주석
- promise반환
- Anaconda
- 1252
- 코드업
- 도전
- 1254
- notion api
- 타이탄의도구들
- 꿈두레
- pygame
- Python
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |