Network security에서 필요한 요구조건
confidentiality: sender와 receiver간 주고 받는 메세지가 둘만 알아보고 제3자가 알아선 안된다.
이를 위해선 암호화 기법을 사용하면 된다.
authentication: 내가 지금 말하고 있는 사람이 내가 원하던 사람인지 확신할 수 있어야한다. 내가 일상생활에서 얘기를 할 때 얼굴을 보고 얘기하니 상대방이 누구인지 아는 것과 같음
message integrity: 내가 말하는 내용들이 변형되지 않고 받아야된다.
access and availability: 서비스를 제공하는 사람은 24시간동안 서비스를 제공할 수 있어야한다. 공격자로부터 서비스를 방어해야한다.
처음 프로토콜을 설계할 때는 보안 요소들을 고려하지 않았다. 따라서 이미 설계된 프로토콜에 보안요소를 덧붙이고 있다.
Alice와 Bob이 있다고 해보자. Trudy는 Alice와 Bob사이의 메세지를 변형시키고, 탈취등의 악영향을 미칠 수 있는 사용자이다. 따라서 Alice와 Bob이 안전하게 메세지를 주고 받을 수 있는 방법에 대해 알아본다.
Alice는 클라이언트, Bob은 서버이다. Trudy는 특별한 누군가가 아닌 우리 중 누구나 될 수 있다. 지금의 인터넷 상황은 모두에게 노출되었기 때문이다. IP 패킷의 헤더에 있는 src, dest 을 통해 인터넷 activity가 다 보인다. 또한, IP 패킷의 data 부분에 있는 TCP segment의 header, application message도 다 보인다. 하지만 HTTPS를 사용한다면 암호화되어 segment는 보이지 않지만, IP 패킷의 src, dest는 보여 패킷이 어디로 가는지는 알 수 있다.
다른 사용자가 내 활동을 모르게하고 싶다면, TOR(익명성 애플리케이션 툴)을 사용하면 어떤 서버에 접근하는지는 가려준다. 이걸 사용하면 익명성이 보장되지만, 굉장히 느리다. 누가 쓰느냐 그럼 ? 추적을 피하기 위해 테러리스트들이 사용한다.
인터넷을 하다보면 warning 사이트를 볼 수 있다. 이는 정부에서 위험한 사이트라고 차단한 것이다. 어떻게 할까? 정부에서 규정한 위험한 서버의 리스트를 만들어 국내에서 국외로 나가는 통로에 전달한다. 따라서 해당 서버로 나가는 길을 차단한다. 따라서 해외의 프록시 서버를 사용해 프록시 서버를 통해 우회해 접근한다.
학교에서도 게이트웨이 라우터에 firewall가 있어 어디로 가는지 모두 알 수 있다.
Alice와 Bob이 메세지를 주고 받고 싶은데 아무도 모르게 하려면, plain text를 trudy가 모르게 암호화하는 과정이 필요하다. 암호화할 때 필요한 요소가 key이다. 따라서 alice가 가진 키를 통해 암호화 하고 bob이 가진 key를 통해 복호화한다.
이렇게 암호화하는 방식을 두가지로 나눌 수 있다.
키 자체가 대칭적으로 같은 것이다. 따라서 alice와 bob이 가진 키가 동일하다. 단순히 기계적인 연산을 통하므로 굉장히 빠르다. 하지만 같은 키를 공유하기 때문에 사전에 미리 만나거나 비밀스러운 채널을 통해 키를 공유해야한다. 따라서 이것이 문제다.
alice와 bob이 사전에 만나지 않아도 키를 공유할 수 있는 방법이 있다. 모든 사람이 두가지 종류의 키를 가지고 있는데, 하나는 모든 사람들에게 공개하는 public 키이고 하나는 자신만 아는 private 키이다. 그러면 alice가 bob에게 보내고자하면 bob을 만나지 않고도 bob의 public key로 암호화하고 보내면 bob이 자신만이 알고 있는 private key로 해독하면 된다. 이를 구현한 것이 RSA이다.
또 다른 특징은 어떤 키를 먼저 적용 시키던 동일한 결과가 나온다는 것이다. 즉, 메세지에 public key를 먼저 적용시키고 private key를 적용시키는 것과 private key를 적용시키고 public key를 적용시키는 것이 동일한 결과를 도출한다는 것이다.
하지만 RSA는 수학적 연산으로 Symmetric key보다 시간이 더 오래걸리고 부담스러운 작업이다. 따라서 메세지 전체를 암호화할때는 Symmetric key 방식을 사용한다. 즉, Symmetric key를 공유할 때 public key 방식을 사용하고 메세지를 암호화할때는 Symmetric key 방식을 사용하는 것이다.
alice와 bob이 이야기 하는데 서로간의 인증(서로 원하는 상대방임을 확인)을 하고 싶을 때 주장만 해서는 해결되지 않는다. 아래와 같이 Trudy도 자신이 alice라고 주장할 수 있기 때문이다. 즉, 다른 사용자가 이들의 메세지를 모니터링 할 수 있으므로 똑같이 전송할 수 있는 것이다.
그래서 alice라고 주장하면, bob이 random한 숫자를 다시 alice에게 보낸다. 이때 alice가 bob과 공유하는 key로 암호화해서 보내면, bob은 이를 같은 key로 복호화해 기존에 보낸 숫자와 같은지 확인한다.
하지만 이는 alice와 bob이 사전에 key를 공유하고 있어야 가능한 일이다. 따라서 public 방법을 사용한다.
alice가 자신이 alice라 주장하면 bob은 랜덤한 숫자인 R을 전송한다. 그러면 alice는 자신의 private key로 R을 암호화해 bob에게 전송한다. bob은 이를 받아 alice의 public key로 복호화해 기존의 R인지 확인한다.
보낸사람이 작성한 메세지가 그대로인가?에 대한 것이다.
우리가 편지를 보낼 때 편지봉투를 닫고 도장이나 테이브 등으로 봉투를 밀봉한다. 이는, reciever가 편지를 받았을 때 도장이나 테이브가 뜯기지 않고 그대로라면 메세지가 변형되지 않았음을 보장한다.
이와 같이 bob이 어떤 메세지를 보내고 싶어할 때 bob의 private key로 encryption할 것이다. 이를 alice가 bob의 public key로 복호화해 읽으면 되는 것이다. 그렇다면 이 말은 bob의 private key로 메세지가 암호화되었다는 것이고, 이 private key는 bob밖에 갖고 있지 않으므로 무결성이 보증되는 것이다.
하지만 위에서도 말했듯 public key 방식을 이용해 메세지 전체를 암호화하는 것은 부담스러운 일이다. 따라서 메세지 전체가 아닌 hash 값을 암호화해서 사용한다. 또한, 자기자신의 private key로 암호화하는 작업은 digitally sign한다고 한다.
메세지 자체를 보내면서 무결성을 보증하기 위해 메세지의 hash 값을 private key로 암호화해 메세지와 같이 보낸다. 그러면 reciever는 이를 받아 메세지를 hash한 값과, sender의 public key로 암호화된 hash값을 복호화해 같은지 확인해 무결성을 검증한다.
즉, alice가 메세지를 보낼 때 bob의 public key로 암호화해 보내 bob이 private key로 이를 복호화하는 것이다. 그렇다면 alice가 사용하는 bob의 public key는 정말 bob의 public key인지 믿을 수 있을까? 그래서 현대에서는 public key에 대한 인증서를 가진다. 이 인증서에는 해당 public key가 누구의 것인지 적혀 있으며 이는 인증기관에 private key로 암호화되어 있다. 따라서 인증기관의 public key를 통해 해당 인증서에 접근할 수 있다. 그렇다면 인증기관의 public key는 어떻게 믿을 수 있을까? 이 인증기관의 public key를 신뢰할 수 없다면 안에 있는 인증서들도 모두 신뢰할 수 없다. 따라서 이 key는 브라우저에 모두 하드코딩되어 있다.
우리가 인터넷을 사용한다는 것은 웹 브라우징 하는 것, 즉 request보내고 response를 받고 하는 것이다. HTTP는 TCP 기반으로 사용되며 HTTP request, response가 모두 TCP socket으로 내려간다. 이때 TCP는 reliable, in-order delivery, flow control, congest control등을 제공해주지만, security는 제공해주지 않는다. 따라서 request, response가 TCP를 통해 전달될 때 다른 사용자에게 모니터링 될 수 있는 것이다.
그래서 보안을 위해 SSL이라는 것을 덧붙였는데 이는 별도의 계층이 아닌 application 계층이다.
그냥 application layer에서 TCP로 내리면 안되므로 SSL을 통해 암호화해서 메세지를 내려보내는 것이다. 따라서 SSL은 HTTP message를 받아 암호화해 TCP로 내려보내는 것이다. 따라서 SSL은 하나의 계층이 아닌 application layer에서 사용하는 인터페이스이다. Secure Sockets Layer의 줄임말이며 요즘은 Transport Layer Security의 줄임말인 TLS을 더 많이 사용한다.
따라서 HTTP 메세지를 SSL을 통해 암호화해서 TCP로 내려보내면 이게 HTTPS이고, SSL을 통해 암호화하지 않으면 HTTP인 것이다. 어떤식으로 동작하는지 살펴보자.
SSL을 사용해 통신을 한다는 것은 기본으로 TCP 기반이라는 것이다.
따라서 아래처럼 소통을 하기 위해선 hello이전에 TCP connection이 형성되어 있어야 한다.
sender가 receiver에게 hello를 보내면 receiver가 public key certificate를 sender에게 보낸다. sender는 이를 받아 인증기관을 통해 public key가 정말 receiver의 것이 맞는지 확인해 receiver의 public key를 알게 되므로 sender는 secret key를 만들어 이를 public key로 암호화해 receiver에게 전송한다. receiver는 이를 받아 복호화하면 된다. 이 secreet key로 이제 둘은 symmetric key 방식으로 소통할 수 있다.
secret key를 통해 4가지 key를 만든다. 4가지 key를 만드는 것은 지정된 함수를 통하므로 key만 알면 가능하다. 왜 4가지나 만들까? 각각의 key들의 기능이 다르기 때문이다.
client와 server가 있다고 하자.
이렇게 역할을 따로 배정해서 사용하는 이유는 key가 유출되었을 때 피해를 최소화하기 위함이다.
우리나라는 사용자들이 인증서를 들고 다니면서 자신을 인증한다. 이러한 방식에선 은행입장이 편리해지는 것이다. 하지만 이 방식의 단점은 해당 은행이 맞는 은행인지 알 수 없다는 것이다.
SSL의 전송단위는 record이다. record는 아래와 같이 구성되어 있으며 data는 application message인 것이다.
MAC은 보안에서 사용하는 언어로 Message Authentification Code의 줄임말이다. 이는 receiver가 받았을 때 데이터가 변형되지 않았고, sender를 확인하기 위함이다. 이 MAC은 공격자가 data를 변형시킬 때 다르게 붙일 수 있으므로 H(data|key)의 형태로 data 뿐만아니라 sender와 receiver 사이의 secret key도 함께 hash한 값을 사용한다. 그러면 공격자는 key를 모르므로 MAC 값을 만들어 낼 수 없는 것이다.
따라서 HTTPS를 사용하면 segment의 data부분에 application messge가 들어가던 것이 record로 들어가는 것이다. 따라서 attacker입장에선 IP packet만 볼 수 있어 어디로 가는지는 알 수 있으나, message는 알 수 없는 것이다. 따라서 attacker가 할 수 있는 것이 굉장히 제한적이다. 어떤일을 할 수 있을까?
attacker가 원하는 것은 client와 server가 모르게 방해하는 것이다. 순서대로 전송되는 패킷안의 record를 서로 바꿔치기 하는 것이다. 즉, pkt1(record1), pkt2(record2)로 가던걸 pkt1(record2), pkt2(record1)와 같이 바꾸는 것이다. 따라서 이를 막기 위해 MAC을 만들 때 sequence number도 같이 넣어 hash하면 된다.
또 attacker가 할 수 있는 것은 data가 다 도착하지 않았는데 SYN 응답을 보내는 것이다. 따라서 데이터가 모두 전송되었는지 까지 SSL이 책임을 져야한다. 따라서 MAC에 type이라는 1비트 짜리를 넣어 0으로 보내다가 마지막 데이터라면 1로 바꿔 보내는 것이다.
record는 아래와 같이 구성된다.
gateway router에 자리하며 외부로 나가는 패킷과 내부로 들어오는 패킷을 감시하는 것이다. gateway router가 내/외부로 향하는 길목이므로 여기에 존재하는 것이다. 따라서 어떤 패킷은 통과시키고 어떤 패킷은 드랍시키게 되는데 이를 위해선 규칙이 필요하다. 이 규칙은 네트워크 운영자가 결정한다.
예를 들어 아래와 같은 정책이 있다.
첫번째 rule을 적용시키기 위해선 TCP header까지 봐야한다. 하지만 라우터에선 IP header까지 볼 수 있는데, firewall이 등장하면서 TCP header까지 보는 것이다. 따라서 layer violation이다.
두번째 정책은 내부 네트워크에 웹사이트를 하나만 운영하고 그 외엔 웹사이트를 금지하는 것이다. 이를 구현하는 것은 내부로 들어오는 TCP SYN packet을 다 drop 한다.
패킷하나하나를 보고 조건에 맞는 것을
첫번째 정책은 외부로 나가지 못하게 하는 것이므로 80 포트로 나가는 패킷을 모두 drop시키면 된다. 그렇다면 학교에서 이러한 정책을 쓰도록 했다고 해보자. 그러면 웹브라우징을 못하게 되므로 학생들의 반발이 심할 것이다.
즉, 관리자의 입장에서는 최대한 막는 것이 안전하지만, 사용자의 편의를 위해 적당히 여는 것이다.
아래는 firewall에 들어가는 rule table이다.
맨 위의 action은 웹 브라우저로 나가는 것을 허용하는 것이다. 그 다음은 들어오는 것을 허용하는 것으로 즉, 위의 action은 request이고, 아래의 것은 response이다.
위의 table을 사용한다고 할 때 SSH를 사용할 수 있을까? SSH는 22번 port를 사용하므로 사용하지 못한다. 또한, TCP 기반에서 request, response가 오고갈때는 TCP connection이 존재해야한다. 하지만 위의 table을 사용해서는 TCP connection이 형성되지 않아도 모두 허용해주는 것이다. 따라서 이제는 TCP connection을 모두 tracking해서 TCP connection이 있는 상황에서만 허용한다.
컴퓨터네트워크 한양대학교 이석복
Computer Networking A Top-Down Approach 7-th Edition