■ HTTP 웹의 기초
● HTTP 개관
○ HTTP 인터넷 멀티미디어 배달부
- 웹 서버로부터 멀티미디어 파일을 웹 브라우저로 옮겨주는 역할
- 신뢰성 있는 데이터 보장 (전송 중 손상되거나 꼬이지 않음)
○ 웹 클라이언트와 서버
웹 브라우저와 같은 클라이언트는 웹 콘텐츠를 가진 웹 서버(HTTP 서버)에 http 객체를 요청한다. ex) /index.html
요청 받은 객체가 있다면 타입, 길이 정보등과 함께 http응답에 실어 클라이언트에게 보낸다.
○ 리소스
# MIME 타입
MIME (multipurpose internet mail extensions)
:수천가지 데이터 타입을 구분하기 위해 객체에 붙이는 데이터 포맷 라벨
-> 멀티미디어 콘텐츠를 기술하고 라벨을 붙이기 위해 채택
*MIME타입을 통해 웹 브라우저는 서버로부터 객체를 돌려 받을 때 다룰 수 있는 객체인지 확인
- 주타입 / 부타입 포맷 ex)image/jpeg
# URI vs URL
: 통상적으로 같은 의미로 쓰임
URI (uniform resource identifier)
: 인터넷에 있는 자원을 나타내는 식별자 (= 인터넷 우편물 주소)
URL (uniform resource locator)
: 인터넷 상의 자원의 위치
protocol + domainName + path + query
- protocol : 원거리 통신 장비 사이에서 메시지를 주고받는 규칙
- domainName : 네트워크 상에서 컴퓨터를 식별하는 호스트명
- path : 요청한 자원에 대한 웹 서버 내 경로
- query : 추가 파라미터
○ 트랜잭션
요청(명령 + url) + 응답 (상태, content-type ....)
# http method
GET - READ
POST - CREATE
PUT - UPDATE
DELETE - DELETE
# 상태코드
200 OK 응답 성공
204 No Content 콘텐츠는 없고 헤더를 보냄
304 Not Modified 캐시목적, 응답이 수정되지 않음
400 Bad Request 잘못된 문법
403 Forbidden 접근 권한 없음
404 Not Found 리소스 찾을 수 없음
504 Gate Way Timeout 적시에 응답하지 못함
○ 메시지
○ TCP 커넥션
HTTP 메시지는 TCP 커넥션을 통해 이동한다
TCP (Transmission Control Protocol)
: 전송제어 프로토콜
TCP/IP
: TCP와 IP가 층을 이루는 패킷 교환 네트워크 프로토콜의 집합
- 서버의 url에서 호스트명을 추출하여 IP로 변환및 포트번호 추출
- TCP 커넥션 맺음
- 요청과 응답
- 브라우저에 문서 띄워줌
○ 웹의 구성요소
프록시(proxy)
:클라이언트와 서버 사이에 위치한 HTTP 중개자
- 주로 보안을 위해 사용
- [필터링] 바이러스 검출, 유해 콘텐츠 차단
캐시
: 많이 찾는 웹페이지를 클라이언트 가까이에 보관하는 창고
게이트웨이
: 다른 애플리케이션과 연결된 특별한 웹 서버
- 서로 다른 네트워크 연결
- 프로토콜간 특수 변환 담당
터널
: 단순히 HTTP통신을 전달하기만 하는 프록시
- raw 데이터를 열어보지 않고 그대로 전달하는 애플리케이션
- ex) 암호화된 SSL 트래픽을 전송하여 사내 방화벽 통과
에이전트
: 자동화된 HTTP 요청을 만드는 웹 클라이언트
● URL과 리소스
○ URL 문법
스킴(어떻게)://서버위치(어디에)/경로(무엇을);파라미터(key=value)?질의(key1=value1&key2=value2)#프래그먼트 구조
○ 안전하지 않은 문자
- 안전하지 않은 문자들을 표현할 수 있는 인코딩 방식 고안
- 퍼센티지 기호로 시작해 16진수로 이루어진 이스케이프 문자로 바꾸어줌
- %, #, ? 등 예약어는 본 목적이 아닌 다른 용도로 사용하기 위해 인코딩을 거쳐야 함
○ 스킴의 바다
# http vs https
- 둘다 기본적인 URL 형식과 같음
- 포트 80 / 포트 400
- https: 암호화하기 위해 보안 소켓 계층인 SSL을 사용한다
● HTTP 메시지
○ 메시지의 흐름
- 클라이언트-> 서버 : 인바운드
- 서버 -> 클라이언트 : 아웃바운드
- 발송자는 업스트림 / 수신자는 다운 스트림
○ 메시지의 각 부분
# 요청 메시지 형식
메서드 유알엘 버전 [무엇을 해야할지]
헤더
엔터티본문
# 응답 메시지 형식
버전 상태코드 사유구절(res msg) [무슨 일이 일어났는지]
헤더
엔터티본문 [MIME 타입, 본문 길이, 내용]
! 헤더의 집합은 항상 CRLF(\r\n)로 끝나야 함을 주의
○ 메서드
○ 상태 코드
1xx 정보
2xx 성공
3xx 리다이렉션
4xx 클라이언트 에러
5xx 서버 에러
○ 헤더
- 일반 헤더 ex) Date
- 요청 헤더 ex) Accept
- 응답 헤더 ex) Server [버전]
- 엔티티 헤더 ex) Content-type
- 확장 헤더
● 커넥션 관리
○ TCP 커넥션
TCP는 세그먼트라는 단위로 데이터 스트림을 잘게 나누고 IP 패킷이라고 불리는 봉투에 담아 데이터를 전달
: 패킷봉투 = 패킷 헤더 + 세그멘트 헤더 + 데이터 조각
- TCP 커넥션의 한쪽에 있는 바이트들은 순서에 맞게 반대쪽으로 정확히 전달됨
- 발신지 IP/포트 + 수신지 IP/포트 => 유일한 커넥션 생성
- 소켓 API 사용시 TCP 종단 데이터 구조를 생성하고 연결하여 스트림을 읽고 쓸 수 있다.
○ TCP의 성능에 대한 고려
성능관련 중요 요소
*참고 - 핸드셰이킹(handshaking)
: 채널에 대한 정상적인 통신이 시작되기 전에 두 개의 실체 간에 확립된 통신 채널의 변수를 동적으로 설정하는 자동화된 협상 과정
- 인터넷 혼잡을 제어하기 위한 TCP의 slow start
- 확인응답 지연 알고리즘
확인응답지연 알고리즘
: 특정 시간동안 버퍼에 데이터를 저장해놓고, piggyback 하기 위한 데이터 패킷을 탐색함. 만약 시간 내에 찾지 못하면 별도의 패킷을 만들어 전송
- 데이터를 한 번에 전송하기 위한 네이글 알고리즘
네이글 알고리즘(Nagle Algoritm)
: 보낼 수 있는 데이터를 바로 패킷으로 만들지 않고, 가능한 모아서 더 큰 패킷으로 만들어 한번에 보내는 알고리즘
- TIME_WAIT 지연과 포트고갈
*커넥션을 끊으면 같은 주소의 포트 번호를 사용하는 새로운 커넥션이 일정시간 동안 생성되는 것을 방지하는 것으로 생김, 따라서 포트번호를 달리해서 요청-> 요청이 많으면 고갈
○ HTTP 커넥션 관리
- 커넥션 헤더로 옵션 지정
- 병렬 커넥션 / 지속 커넥션 / 파이프라인 커넥션
- Connection:Keep-Alive 이용 시 proxy 주의
- 과부하 방지를 위하여 넉넉잡아 2개의 지속 커넥션만 유지하는 것이 좋음
- 병렬 커넥션과 지속 커넥션 함께 사용
- POST와 같이 반복해서 요청을 보내는 경우 중간에 에러 발생 시 어떤 것들이 처리되었는지 모르기 때문에 파이프라인을 통해 보내면 안됨
- 중간에 끊어지는 문제가 있을 수 있기 때문에 정확한 Content Length를 가지고 있어야 함
- 입력채널을 끊기보다는 출력채널을 끊는 것 권장
■ HTTP 아키텍처
● 웹 서버
○ 진짜 웹 서버가 하는 일
HTTP 요청 처리 및 응답
: ex) Apache, nginx
# 수행 단계
1) 커넥션을 맺음
2) 요청을 받음
3) 요청을 처리
4) 리소스 접근
5) 응답 생성
6) 응답 전달
7) 트랜잭션을 로그로 남김
○ 리소스 호스트명 식별
- 역방향 dns를 통해 클라이언트의 호스트명 식별(호스트명 룩업)
- 접근제어와 로깅을 위해 사용 가능
- 시간이 걸릴 수 있으므로 주의
○ 요청 메시지 수신과 처리
- 요청 메시지를 파싱하여 메서드, 식별자, 버전번호를 찾음
- 헤더와 본문을 읽음 (CRLF로 구분)
- 요청 메시지를 더 쉽게 다룰 수 있도록 내부 자료구조애 저장
- 단일 스레드/ 멀티프로세스와 멀티스레드/ 다중IO/ 다중 멀티스레드로 처리
○ 리소스의 매핑과 접근
Docroot
: 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약
- 가상 호스팅으로 분리된 문서루트를 제공
- 대부분의 웹 서버는 요청한 URL에 대응되는 디렉터리 안에서 index.html 파일을 찾음
- 동적 콘텐츠 매핑 가능
○ 응답 메시지 생성
# 리다이렉션을 하는 경우
- 리소스가 옮겨진 경우
- 과부하된 서버 요청 받을 때
- 친밀한 다른 서버가 존재
- 디렉터리 이름 정규화
○ 로깅
트랜 잭션이 완성 되었을 때 어떻게 수행되었는지에 대한 로그를 로그 파일에 기록
- HTTP 메서드
- 클라이언트와 서버의 HTTP 버전
- 요청받은 리소스의 URL
- 응답의 HTTP 상태코드
- 요청과 응답 메시지의 크기
- 트랜잭션이 일어난 시간
- Referer와 User-Agent 헤더 값
● 캐시
웹캐시
자주쓰이는 문서의 사본을 자동으로 보관
- 불필요한 데이터 전송을 줄임 (비용 절감)
- 갑작스러운 요청 쇄도(Flash Crowds) 발생 시 불필요한 트래픽 급증을 방지
- 서버 부하를 줄임
- 대부분의 로컬 네트워크 클라이언트가 원격서버보다 더 넓은 대역폭을 제공 (대역폭을 늘리지 않고도 페이지를 빨리 불러 올 수 있음)
- 거리로 인한 지연 문제 방지
- 시간 지연 방지
○ 적중과 부적중
캐시 적중
: 캐시에 요청이 도착했을 때 대응하는 사본이 있다면 요청 처리
- 원 서버 콘텐츠는 변경될 수 있기 떄문에 사본이 최신인지 점검해야함
- 효과적인 재검사를 위해 HTTP는 서버로부터 빠르게 검사할 수 있는 특별한 요청을 정의
# If-Modified-Since(IMS) 헤더 : 캐시된 시간 이후 변경된 경우에만 사본 전송 바람
서버 객체 변경 O Status 200 & 새 본문
서버 객체 변경 X Status 304 (Not Modified)
서버 객체 삭제됨 Status 404 (Not Found)
- 캐시적중과 원 서버 접근 구분 불가 (둘다 200 OK) -> 헤더 정보 이용
- 속도 : 적중 > 재검사 적중(느린 적중) > 부적중
○ 캐시 토폴로지
토폴로지(topology)
: 컴퓨터 네트워크의 요소들(링크, 노드 등)을 물리적으로 연결해 놓은 것, 또는 그 연결 방식.
- 캐시 계층을 생성해 보다 합리적
- 몇몇 아키텍처는 단순한 캐시 계층 대신 복잡한 캐시망을 만들어 캐시 커뮤니케이션 결정을 동적으로 내림
- 웹 브라우저는 개인전용 캐시를 내장하는데, 자주쓰이는 문서를 개인용 컴퓨터의 디스크와 메모리에 캐시해 두고 사용자가 설정을 수정할 수 있도록 허용함
- 공용 캐시는 특별한 종류의 공유된 프락시 서버로 불필요한 트래픽을 줄일 수 있는 더 많은 기회가 있음
○ 캐시 처리 단계
1) 요청 받기 - 요청 메시지를 읽음
2) 파싱 - 메시지를 파싱하여 URL과 헤더들을 추출
3) 검색 - 로컬 복사본이 있는지 검사하고 없으면 사본을 받아 로컬에 저장
4) 신선도 검사 - 사본이 충분히 신선한지 검사하고 변경사항이 있는지 서버에게 물어봄
5) 응답 생성 - 응답 메시지 생성
6) 발송 - 응답을 클라이언트에게 돌려줌
7) 로깅 - 로그파일에 대한 로그를 선택적으로 남김
! 캐시가 Date 헤더를 조정해서는 안됨 (원 서버에서 최초로 생겨난 일시를 표현)
○ 사본을 신선하게 유지하기
- Cache-Control과 Expires라는 헤더를 통해 문서 유효기간을 붙일 수 있음
- 문서 만료는 문서의 다름을 의미하는 것이 아니라 재검사가 필요함을 의미
-If-Modified-Since(날짜 재검사) / IF-None-Match(엔티티 태그 재검사)
- 강한 검사기 / 약한 검사기 (그 정도면 같은 것이라 간주 \W)
- 엔터티 태그 값은 재활용 해서는 안됨
- 서버가 반환한 정보에 따라 검사 방법 선택
○ 캐시 제어
HTTP는 문서가 만료되기 전 얼마나 오랫동안 캐시될 수 있게 할 것인지 설정 방법 정의
- [Cache Control] no-store/no-chache: 검증되지 않은 캐시 객체 응답 막음
- [Cache Control] must-validate: 신선한 객체만 제공받음
- [Cache Control] max-age / Expires: 유효기간 설정
- 휴리스틱: 경험적 방법으로 설정
○ 자세한 알고리즘
$ 충분히 신선한가 = $나이 < $ 신선도 수명
$겉보기_나이 = max(0, $응답을_받은_시각 - $Date_헤더값)
$보정된_겉보이_나이 = max($겉보기_나이, $Age_헤더값)
$응답_지연_추정값 = $응답을_받은_시각 - $요청을_보낸_시각;
$문서가_우리의_캐시에_도착했을_때의_나이 = $보정된_겉보기_나이 + $응답_지연_추정값;
$사본이_우리의_캐시에_머무른_시간 = $현재_시각 - $응답을_받은_시각;
$나이 = $문서가_우리의_캐시에_도착했을_때의_나이 + $사본이_우리의_캐시에_머무른_시간;
서버 만료 정보 + 클라이언트 신선도 요구사항 => 신선도 수명 판별
○ 캐시와 광고(접근 횟수가 필요할 때)
캐시가 접근 횟수를 숨길 수 있고 흡수함
-> 트래픽은 흡수하도록 두되 정기적으로 적중 횟수를 건네 받아야 함
-> 적중 횟수를 정기적으로 서버에게 돌려주는 Meter 헤더 추가로 캐시 적중량 측정 및 리소스 사용량 제어를 통한 사용량 제한
● HTTP/2.0
○ HTTP/2.0의 등장 배경
- HTTP/1.1의 메시지 포맷은 구현의 단순성과 접근성에 주안점을 두고 최적화 되어 어느정도의 성능은 희생됨
- 회전지연 발생 -> 병렬,파이프라인 커넥션 도입 -> 근본적 해결책은 아님
- 구글 SPDY 등장 (헤더 압축, 하나의 커넥션에 요청 여러개 동시에 보냄, 서버 능동적 푸쉬)
- SPDY 기반으로 HTTP/2.0 설계
○ 개요
- 요청과 응답은 한 개 이상의 프레임에 담김
- 프레임에 담긴 요청과 응답은 여러개의 스트림을 통해 전달(동시 처리 가능)
스트림
: 클라이언트와 서버 사이에서 교환되는 프레임들의 독립된 양뱡향 시퀀스, 한쌍의 요청과 응답은 하나의 스트림으로 이루어짐
- 스트림에 대한 흐름제어와 우선순위 부여 가능
- 서버 푸시(능동적 클라이언트에게 정보 전달)
- 호환성 유지를 위해 요청/응답 메시지의 의미는 1.1과 같도록 유지
- 문법은 살짝 변경됨
○ HTTP/1.1과의 차이점
- 프레임 존재 (종류에 따라 페이로드의 형식과 내용 상이)
- 스트림과 멀티플렉싱
서버와 클라이언트는 협상없이 스트림을 만듬(시간 절약)
스트림에 할당하는 식별자가 고갈되면 커넥션을 다시 맺음
- 헤더 압축 (압축 컨텍스트 사용)
압축해제 사용 불가 시 커넥션 끊음
- 서버 푸시
PUSH_PROMISE 프레임을 먼저 보내 자원을 푸시할 것을 알려주면서 클라이언트가 별도로 또 요청하는 것을 방지 (요청 스트림을 통해 전달), 동일 출처 정책 검사
○ 알려진 보안 이슈
- 중개자 캡슐화 공격
- 긴 커넥션 유지로 인한 개인정보 누출 우려
■ 식별, 인가, 보안
● 클라이언트 식별과 쿠키
○ 개별 접촉
- HTTP는 익명으로 사용하며 상태가 없고 요청과 응답으로 통신
- 웹 서버는 클라이언트를 식별하거나 방문자가 보낸 요청를 추적하기 위해 약간의 정보를 이용할 수 있음
- 사용자들이 브라우징 하는 것을 기록하여 개인화 하고자 함
○ HTTP 헤더
HTTP 헤더 - MDN
From
요청하는 유저 에이전트를 제어하는 사용자(사람)의 인터넷 이메일 주소를 포함
User-Agent
네트워크 프로토콜 피어가 요청하는 사용자 에이전트의 애플리케이션 타입, 운영 체제, 소프트웨어 벤더 또는 소프트웨어 버전을 식별할 수 있는 특성 문자열을 포함,
! 사용자가 누군지는 알 수 없음
Referer
현재 페이지로 연결되는 링크가 있던 이전 웹 페이지의 주소
○ 클라이언트 IP 주소
사용시 단점
- 사용자가 아닌 사용하는 컴퓨터를 가리킴
- 많은 인터넷 서비스 제공자는 동적으로 IP주소를 할당 - 식별 불가
- IP는 방화벽에 의해 가려자는 경우가 많음
=> 제대로 추적 불가
○ 사용자 로그인
- WWW-Authenticate [401 Authorization Require] / Authorization으로 아이디와 비밀번호를 요청 및 전달
- 이 시점 이후의 요청에 대해 브라우저는 서버로부터 식별정보를 요청받으면 심지어 요청을 하지 않았을 때에도 로그인 정보를 전달함(토큰으로 세션 유지)
- 사용자에게 귀찮은 일이라는 단점
○ 뚱뚱한 URL(URL에 식별자 포함)
첫 방문시 ID생성 후 URL에 추가 > 리다이렉트
- 사용자의 상태정보를 포함
- 상태정보를 유지하며 하이퍼링크를 동적으로 생성
- 개인정보 유출
- 혼란을 주는 URL
- 캐시 사용 불가
- 뚱뚱한 URL에 해당하는 페이지로 다시 그려야함
- 이탈과 지속성 부재 문제
○ 쿠키 (강력하면서도 효율적)
HTTP 특징인 비연결지향과 상태없음을 보완하고 세션관리, 트래킹 등을 위해 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각
(≒ 카운터 키)
- 사용자를 식별하고 세션을 유지하는 방식 중 가장 많이 쓰임
- 새로운 HTTP헤더 정의
- 캐시와 충돌할 수 있어 쿠키에 있는 내용물을 캐싱하지 않음
- 유일한 값을 쿠키에 할당
- 임의의 이름=값 형태의 리스트를 가지고 Set-Cookie같은 HTTP응답 헤더에 기술되어 사용자에게 전달
- 브라우저는 개인정보 보호와 성능문제, 최적화를 위해 두세개의 쿠키만을 보냄
- 쿠키를 생성한 서버에게만 쿠키에 담긴 정보를 전달
- 보안 문제와 트래픽이 단점
- Version 1 (RFC 2965 쿠키) :웹 표준에서 제거 됨
Cookie2
HTTP 상태관리 체계
: 브라우저가 서버 관련 정보를 저장,
사용자가 서버 접근시 이를 전송,
브라우저는 쿠키 정보를 저장할 책임이 있음
# 쿠키의 타입
만료 시간 존재할 때 지속쿠키, 없으면 세션쿠키
(Discard, Expires, Max-Age)
쿠키 이름 | 특징 |
---|
Session Cookie | 만료시간를 설정하고 메모리에만 저장되며 브라우저 종료시 쿠키를 삭제 |
Persistent Cookie | 장기간 유지되는 쿠키, 파일로 저장되어 브라우저 종료와 관계없이 사용 |
Secure Cookie | HTTPS에서만 사용, 쿠키 정보가 암호화 되어 전송 |
Third-PartyCookie | 방문한 도메인과 다른 도메인의 쿠키, 유입 경로를 추적하기 위해 사용 |
# 쿠키의 속성 (Set-Cookie)
속성 | 설명 |
---|
Name=Value | 쿠키의 이름과 저장된 값 |
Expires | 만료기간 설정 |
Domain | 도메인 지정, 현재 탐색 중인 도메인과 일치하지 않을 경우, "타사 쿠키"로 간주 |
Path | 도메인 내 진입가능한 특정 경로 설정 |
Secure | 보안 연결 설정 |
HttpOnly | HTTP외에 다른 통신 사용 가능 설정 |
# 쿠키와 캐싱
- 이전 사용자에게 할당, 개인정보가 누출되는 등의 상황을 막기위해 쿠키 사용시 캐싱하는 것에 주의
- 캐시되지 말아야할 문서가 있다면 표시해야함 (Cache-control)
- Set-Cookie 헤더를 캐시하지 않도로고 주의
- 재검사가 일어나게 하여 보완
# 참고
간단한 실습
쿠키와 세션의 차이
● 기본 인증
401 Authorization Require: 인증방법 설명
○ 기본 인증
- 프록시 인증을 사용하기도 함
- 보안에 취약한 면이 있음
인증요구(서버 -> 클라이언트) | WWW-Authenticate: Basic realm="OOO"
응답(클라이언트 -> 서버) | Authorization : Basic Base-64로 인코딩된 정보
● 보안 HTTP
○ HTTP를 안전하게 만들기
HTTPS(Hypertext Transfer Protocol Secure) 사용
: HTTP의 보안이 강화된 버전
- 애플리케이션 계층과 전송 계층 사이에 보안 계층 존재
-> 네트워크로 보내지기 전 암호화
- SSL(보안 소켓 계층)을 사용함
- SSL은 서버와 브라우저 사이에 안전하게 암호화된 연결을 만들 수 있게 도와주어 도난을 막음
- 검색엔진 최적화(SEO)에 있어서도 큰 혜택
- http 스킴을 가지고 있다면 80번포트로 연결 후 평범한 명령 전송
- https 스킴을 가지고 있다면 443포트로 연결 후 SSL 매개변수를 교환하며 핸드셰이크를하고 암호화된 명령 전송
SSL(Secure Sockets Layer)
: 네트워크에 통신 보안을 제공하기 위해 설계된 암호 규약
SSL 핸드셰이크 과정
출처: https://itsaessak.tistory.com/168
사이트 인증서 검사
- 날짜 검사
- 서명자 신뢰도 검사
- 서명 검사
- 사이트 신원 검사
○ 디지털 암호학
# 기본지식 및 용어
용어 | 설명 |
---|
키 | 암호의 동작을 변경하는 숫자로 된 매개변수 |
대칭키 암호 체계 | 인코딩과 디코딩에 같은 키를 사용하는 알고리즘, 수가 많고 관리가 어려움 |
공개키 암호법 | 비밀 메시지를 전달하는 수백만대의 컴퓨터를 쉽게 만들 수 있는 시스템, 두 개의 비대칭키 사용, 인코딩 키는 공개되어있음, 디코딩은 소유자만 가능, 느린 경향이 있어 대칭과 섞어사용 |
디지털 서명 | 위조 혹은 변조되지 않았음을 입증 |
디지털 인증서 | 신뢰할 만한 조직에 의해 서명되고 검증된 신원 확인 정보 |
○ 프락시를 통한 보안 트래픽 터널링
- 웹 서버에 접근해주는 웹 프락시 서버를 이용할 때 proxy가 알아 들을 수 있도록 암호화 하기 전에 CONNECT라 불리는 새로운 확장 메서드를 이용해 희망 호스트와 포트번호로 연결 요청
CONNECT home.netscape.com:443 HTTP/1.0
User-Agent: Mozilla/1.1N
~SSL로 암호화된 데이터 ...~
엄샐리님 소문듣고왔습니다