2012-12-26 3 views
1

우리는 WebSocket을 사용하여 EC2 인스턴스와 통신합니다. 스크립트는 nodejs와 Express를 사용하여 제공되고 WebSocket을 초기화합니다. 지금 ELB가 사용되어 클라이언트 IP를 식별하는 것이 어려워집니다. x-forwarded-for 헤더를 사용하면 HTTP 컨텍스트에서 IP를 얻을 수 있지만 서버의 WebSocket 컨텍스트에서는 Amazon에서 전달하지 않는 것처럼 보입니다. (공개 DNS를 사용하여) WebSocket을 통해 Amazon ELB 또는 직접 (원격 IP 문제)

  1. 인스턴스와 직접 웹 소켓을 통신 :

    우리는이 옵션을 확인했다.
  2. HTTP의 컨텍스트에있을 때 IP를 저장하고 세션 ID와 연결하는 일종의 sessionid를 유지 관리합니다. 클라이언트 측에서는 HTTP 응답을 사용하여 sessionid를 가져와 WebSocket에 사용합니다. 서버는 클라이언트를 식별하고 캐시에서 IP를 분석합니다.

두 옵션 모두 훌륭하지 않습니다. 1은 내결함성이없고 2는 복잡합니다. 더 많은 솔루션이 있습니까? Amazon이 어떻게 IP를 전달할 수 있습니까? 가장 좋은 방법은 무엇입니까?

감사

+0

초기 http뿐만 아니라 websocket에도 포트 80을 사용하고 있습니까? –

+0

아니요, 이제 websocket이 다른 포트를 통과합니다. – whadar

+0

참고 : http://stackoverflow.com/q/17981943/201952 – josh3736

답변

1

나는 WebSocket을 일한 나는 ELB와 함께 일했다,하지만 난 함께 일한 적이없는, 그래서 나는 탄성로드 밸런서에 HTTP 전달자가 이해하지 못하는 것을 몰랐어요 websocket 요청 ...

그래서 나는 당신이 다른 포트를 사용하는 이유를 설명하는 TCP 전달자를 사용해야하며 물론 TCP 전달자는 프로토콜을 인식하지 못하기 때문에 추가되지 않을 것입니다 모든 헤더.

상당히 일반적인 것 같고 복잡하지 않은 옵션은 응용 프로그램의 http 측에서 검색을 위해 캐시에 저장하는 대신 정보를 밀어서 웹 소켓 측에 조언하는 것입니다. 환경에 구현하기가 어렵거나 불가능한 장애물이 없다고 가정 할 때 확장 성과 가벼움을 제공합니다.

websocket을로드하는 웹 페이지를 생성하는 동안 문자열 "ipv4 :"및 클라이언트의 IP (예 : "192.168.1.1")를 가져 와서 연결하고 암호화하여 결과가 URL로 작성되도록하십시오 :

128 개 비트 AES와 그 예를 들어 키와 그 예를 들어, IP 주소를 사용 는
/* pseudo-code */ 
base64_encode(aes_encrypt('ipv4:192.168.1.1','super_secret_key')) 

, 내가 얻을 :

/* actual value returned by pseudo-code above */ 
1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk= 

을 그리고 동적 URL 구축의 웹 소켓을 포함하고있는 페이지의 HTML을 렌더링 할 때 :

ws = new WebSocket('ws://example.com/sock?client=1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk='); 

websocket의 쿼리 문자열이 코드에 액세스 할 수 있다고 가정하면 super-secret 키를 사용하여 "client"쿼리 매개 변수에서 찾은 문자열을 base64_decode 한 다음 aes_decrypt 한 다음 "ipv4 : "... 그렇지 않다면 그것은 합법적 인 가치가 아닙니다.

물론 "ipv4 :"(문자열 시작 부분) 및 "client"(쿼리 매개 변수 용)는 임의의 선택이었으며 실제로 중요한 의미가 없습니다. 내가 선택한 128 비트 AES도 임의적이었습니다.

물론이 설정에서는 문제가 재생됩니다. 즉, 주어진 클라이언트 IP 주소는 항상 동일한 값을 생성합니다. 로깅이나 디버깅과 같은 "정보 제공"을 위해서만 클라이언트 IP 주소를 사용한다면 충분할 수 있습니다. , 수신 측에

'ipv4:192.168.1.1;valid:1356885663;' 

을 문자열을 디코딩하고 타임 스탬프를 확인 : 예를 들어, 타임 스탬프를 추가하여 - 당신이 더 중요한 것을 위해 그것을 사용하는 경우, 당신은이 구현을 확장 할 수 있습니다. +/- 당신이 안전하다고 생각하는 시간 간격 (초 단위)이 아니면, 그것을 신뢰하지 마십시오.

이러한 제안 동적 웹 소켓 URL을 생성 할 수있는 능력의 모든 힌지, 브라우저의 능력은 그것으로 연결, 당신은 웹 소켓 요청에서 URL의 쿼리 문자열 부분에 액세스 할 수있는 ...하지만 경우에 그 조각 것이다 어쩌면 이것이 도움이 될지도 모른다. (주석에서)


추가 생각 :

내가 제안 타임 스탬프, 위의, 당신에게 당신의 플랫폼에서 더 statefulness 필요하지 않습니다 증분 카운터를 제공하는 seconds from the epoch입니다 - 그것은 단지 필요로하는 모든 당신의 서버 클럭이 정확하므로 불필요한 복잡성이 추가되지 않습니다. 해독 된 값에 서버의 현재 시간과 다른 (예 :) 5 초 미만의 타임 스탬프가 포함되어 있으면 인증 된 클라이언트를 처리하고 있음을 알 수 있습니다. 허용되는 시간 간격은 원본 페이지를로드 한 후 클라이언트가 웹 소켓 연결을 시도 할 수있는 최대 시간과 모든 서버 시계의 최대 기울기를 더한 시간이어야합니다.

물론 NAT를 사용하면 동일한 원본 IP 주소 뒤에 여러 사용자가있을 수 있습니다. 사용자가 실제로 첫 번째 http 연결을 시작한 곳과 다른 소스 IP에서 websocket 연결을 만들 수 있지만 여전히 합법적 인 것은 사실입니다. 인증 사용자는 실제 소스 IP보다 더 중요한 가치 일 수 있습니다.

암호화 된 문자열에도 인증 된 사용자의 ID를 포함 시키면 원래 IP, 사용자 계정 및 시간에 고유 한 값이 1 초의 정밀도로 적용됩니다. 나는 이것이 당신이 소금을 추가로 언급하고있는 것이라고 생각합니다. 문자열에 사용자 계정을 추가하면 원하는 정보를 얻을 수 있습니다.

'ipv4:192.168.1.1;valid:1356885663;memberid:32767;' 

TLS는 권한이없는 자에 의해이 암호화 된 문자열의 발견을 방지해야하지만, 생성 된 URL은 HTML 페이지에 대한 사용자의 브라우저의 '소스보기'에서 일반 텍스트로 사용할 수 있기 때문에 다시 플레이의 방지도 중요하다. 오늘 승인되었지만 내일 권한이없는 사용자가 더 이상 유효하지 않은 것으로 인식되어야하는 서명 된 문자열로 스푸핑 할 수 없도록하려는 경우 시간 소인을 입력하고 매우 작은 유효한 창에 떨어지도록 요구하면이를 방지 할 수 있습니다.

+0

감사합니다. 통찰력있는 아이디어. 재생에 관해서는 TLS를 통한 WS를 사용하고 정확한 메시지가 도착했는지 확인하는 증분 카운터를 서버에서 유지 관리 할 수 ​​있습니다. 또한 NAT 뒤에 있으며 동일한 IP를 사용할 수있는 클라이언트가 거의 없습니다. 따라서 일부 소금은 암호화를 차별화하는 데 도움이 될 수 있다고 생각합니다. – whadar

+0

나는 몇 가지 추가적인 생각을 가지고 대답을 확장했다. –

+0

_ "('? WS : 클라이언트 = 1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk = //example.com/sock')'WS = 새로운 웹 소켓 웹 소켓을 포함하고있는 페이지의 HTML을 렌더링 할 때 그런 다음, 동적 URL을 구축,'"_ 내가 가진 문제는 스크립트가 캐시에 적합하지 않다는 것입니다. 또한 스크립트를 호스팅하여 고객 서버에 호스트하는 것과 비교하여 스크립트를 호스팅하지 않습니다 (SaaS 솔루션이므로 일반적으로 문제가되지 않습니다). – whadar

0

응용 프로그램의 심각성에 따라 다릅니다.

클라이언트 IP 주소에 대한 모든 종류의 결정을 기반으로하는 것은 위험한 제안입니다. 보안 강화, 훨씬 더 그렇습니다. 지금까지 제안 된 제안은 주어진 제약 조건 내에서 잘 작동하지만 강력한 엔터프라이즈 애플리케이션에는 충분하지 않습니다.

클라이언트 IP 주소는 이미 지적했듯이 NAT에 의해 가려 질 수 있습니다. 따라서 직장에서 웹에 액세스하는 사람들은 종종 동일한 IP 주소를 갖는 것으로 보입니다.집에있는 사람의 라우터는 NAT로 작동하므로 집에있는 모든 가족 구성원이 동일한 IP 주소를 사용하게됩니다. 또는 심지어 같은 사람이 PC 및 타블렛에서 응용 프로그램에 액세스 할 수 있습니다 ...

NAT 뒤에 있는지 여부에 상관없이 동일한 컴퓨터에서 두 브라우저의 응용 프로그램을 사용하면 같은 주소를 가지고 나타납니다. 마찬가지로, 동일한 브라우저의 여러 탭에 동일한 주소가 표시됩니다.

프록시 또는로드 밸런서와 같은 다른 연결 지점은 원래 클라이언트 IP 주소를 숨기므로 프록시 /로드 밸런서 뒤에있는 것이 클라이언트라고 생각할 수 있습니다. (보다 정교하거나 낮은 수준의 중개자가이를 막을 수 있기 때문에 더 정교하거나 비싸게 만들 수 있습니다.)

위의 내용을 감안할 때 심각한 응용 프로그램은 중요한 결정에 대해 클라이언트 IP 주소에 의존하면 안됩니다 보안 관련.

+0

동의 - IP 기반 결정을 내리는 것이 좋습니다. 하지만 WebSocket 서버 측 처리기 내에서 IP가 포함될 컨텍스트를 유지하려고합니다. – whadar

관련 문제