[우아한테크코스] 5월 20일 TIL
[infra] SSL/TLS
-
Secure Sockets Layer
웹사이트와 브라우저 사이에 전송된 데이터를 암호화하여 보안을 유지하는 표준 기술(프로토콜) -
Trasport Layer Security
Application Layer <—-TLS Layer—-> Transport Layer
핸드셰이크 과정- Client Hello: 클라이언트는 서버에게 지원 가능한 방식(암호, 키교환, 서명 등)을 서버에 알려준다.
- Server Hello: 서버는 클라이언트에게 지원 가능한 방식을 응답
- Certificate Message: 서버는 공개키(RSA 암호)가 포함된 서버 인증서 클라이언트에 발송
- Server Hello Done: 서버의 전송 끝나면 메시지 전달
- Client Certificate: 서버가 클라이언트 인증서를 요구할 때 클라이언트가 서버에 인증하기 위한 SSL 인증서 전송
- 클라이언트는 전송받은 서버 인증서가 유효한지 확인하고, 세션키로 사용될
Pre-Master Key
를 랜덤으로 생성해 공개키로 암호화해 서버로 전송, ClientKeyExchange 메시지에 Pre-Master Key가 포함된다. - 서버는 자신의 개인키로 클라이언트에게 전송받은 세션키(대칭키) 복호화해서
Pre-Master key
를 알아낸뒤 이를 이용해 master secret 생성
이후로 master secret에서 세션 키 생성해내고 서버-클라이언트 간 통신을 암호화하는 데에 사용한다. - 서로에게
ChangeCipherSpec
메시지를 보내고,Finished
메시지를 보내 과정이 끝남을 알린다.
[network] LAN vs WAN
- Local Area Network
공유기나 스위치를 이용해 연결된 회사, 집 등의 지역 네트워크
ethernet 프로토콜 TCP/IP 사용 - Wide Area Network
LAN과 LAN 사이를 광범위한 지역 단위로 구성하는 네트워크
전용선, 회선 교환, 패킷 교환, 셀 릴레이 사용해 연결
[infra] Reverse Proxy
Internet <–> Proxy <–> Web server
was가 비즈니스 로직만 담당하도록 하고 TLS와 같은 부수적인 기능으로 영향을 주고 싶지 않을 때 사용
보안성(백엔드 infra 숨김), 확장성, 웹 속도 향상, 압축/ssl 처리로 백엔드 자원 확보/캐싱
Reverse Proxy
는 클라이언트로부터 요청을 받아서 적절한 웹 서버로 요청 전송 -> 웹 서버는 요청 받아 처리 후 reverse proxy
로 반환 -> reverse proxy
는 응답을 클라이언트로 반환
- (foward) proxy: LAN -> WAN 요청 대리 수행, 여러 클라이언트에 대한 프록시
- reverse proxy: WAN -> LAN 요청 대리 수행, 여러 서버에 대한 프록시
ex) nginX
참고
[network] load balancer
서버에 접근하는 작업량을 분산시켜 부하를 분산해주고, 서버상태를 체크하고, 세션 관리를 해준다.
사용 알고리즘
- round robin: 요청을 순서대로 각 서버에 배분
- Least Connection: 서버에 연결되어 있는 수가 가장 적은 서버에 연결
- Weighted Least Connection: 서버의 처리 능력에 가중치를 두어 가중치와 least conneciton을 종합 판단해 적절한 서버에 연결
- Fastest Response Time: 가장 빨리 응답하는 서버에 연결
- Hashing: 사용자의 IP를 해싱해 연결, 동일한 사용자는 동일한 서버에 연결
종류
- L4: Transport layer에서 수행, 패킷 레벨에서 밸런싱해 빠르고 안전, 저렴, 섬세한 라우팅 불가능, 연속적인 서비스 제공 불가
- L7: Application layer애서 수행, 캐싱 기능, 섬세한 라우팅, 비정상적인 트래픽 사전 필터링 가능, 비쌈, 보안 상 위험
이점
- 비용 절감
- SPOF 해결: 단일 서버 에러 발생 시 모든 동작 불가능한 것 해결
- 확장 용이성: 더 많은 사용자에 대해 서버 확장 시 용이
[infra] reverse proxy 설정
- 도커 설치
sudo apt-get update && \ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \ sudo apt-key fingerprint 0EBFCD88 && \ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ sudo apt-get update && \ sudo apt-get install -y docker-ce && \ sudo usermod -aG docker ubuntu && \ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ sudo chmod +x /usr/local/bin/docker-compose && \ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
- Reverse Proxy 설정
- 프로젝트 파일 최상단에
Dockerfile
생성FROM nginx COPY nginx.conf /etc/nginx/nginx.conf
- 프로젝트 파일 최상단에
nginx.conf
파일
``` events {}
http { upstream app { server 127.0.0.1:8080; }
server { # 80으로 요청이 오면 localhost 의 8080포트로 연결해준다는 의미예요. listen 80;
location / {
proxy_pass http://app;
} } } ```
-
docker로 실행
docker build -t nextstep/reverse-proxy:0.0.1 .
docker run -d -p 80:80 --name proxy nextstep/reverse-proxy:0.0.1
-
통신 확인
telnet localhost 80
curl localhost 80
[infra] TLS 설정
- letsencrypt를 이용한 TLS 인증서 사용
let’s encrypt 무료 인증 기관$ docker run -it --rm --name certbot \ -v '/etc/letsencrypt:/etc/letsencrypt' \ -v '/var/lib/letsencrypt:/var/lib/letsencrypt' \ certbot/certbot certonly -d '[도메인명]' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
위 명령어 실행하면 나오는 값을
- 도메인 설정한 곳에서 DNS TXT 도메인 이름과 value 추가
reverse proxy에 TLS 설정
- 인증서 옮기기
$ cp /etc/letsencrypt/live/[도메인주소]/fullchain.pem ./ $ cp /etc/letsencrypt/live/[도메인주소]/privkey.pem ./
- Dockerfile에 추가
COPY fullchain.pem /etc/letsencrypt/live/[도메인주소]/fullchain.pem COPY privkey.pem /etc/letsencrypt/live/[도메인주소]/privkey.pem
- nginx.conf 파일 추가
# Redirect all traffic to HTTPS server { listen 80; return 301 https://$host$request_uri; } server { listen 443 ssl; ssl_certificate /etc/letsencrypt/live/[도메인주소]/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/[도메인주소]/privkey.pem; # Disable SSL ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 통신과정에서 사용할 암호화 알고리즘 ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5; # Enable HSTS # client의 browser에게 http로 어떠한 것도 load 하지 말라고 규제합니다. # 이를 통해 http에서 https로 redirect 되는 request를 minimize 할 수 있습니다. add_header Strict-Transport-Security "max-age=31536000" always; # SSL sessions ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; location / { proxy_pass http://app; } }
-
프록시 중지, 재시작
- 설정 파일 나누기
application-local.properties
application-test.properties
application-prod.properties
로 나누어서 설정을 하고
$ java -jar -Dspring.profiles.active=prod [jar파일명]
옵션을 주고 실행하면 특정 설정 파일로 실행
[network] 네트워크 스캐닝
네트워크를 통해 제공하고 있는 서비스, 포트, host 정보 등을 알아내는 것
Nmap, WPScan, Nikto, Netcat 등을 이용해 스캔할 수 있음
서버의 상태, 사양, 취약점과 같은 각종 정보를 쉽게 탐색
- WPScan을 사용한 탐색 방법
–url : 해당 url의 워드프레스 사이트를 스캐닝한다.
–username : 해당 사용자 이름으로 Brute Force Attack을 실행한다.
–wordlist : 지정한 워드리스트를 이용하여 패스워드 Brute Force Attack을 실행한다.
–enumerate p : 해당 워드프레스에 설치된 플러그인을 열거한다. (u: 사용자 이름, vp: 취약점 있는 플러그인, vt: 취약점 있는 테마)
위 옵선을 이용해 원하는 값 도출 ex)wpscan --url http:128.0.0.1/hi --enumerate p
[network] wireshark의 사용
네트워크 패킷을 캡처하고 분석하는 도구
네트워크로 돌아다니는 패킷(데이터)을 수신해 저장
- 패킷 스니핑
네트워크 상에서 자신 이외의 사용자들의 패킷을 엿보는 것
tcp/ip 통신은 평문 통신을 하기에 스니핑에 취약
display filter -> string, packet details로 바꾸고 날라가는거 찍어보면 평문화인지 볼 수 있음
따라서 스니핑을 방지하기 위해 TLS 사용