TCP 연결을 수락하기 전에 피어 주소를 확인할 수 있습니까?

TCP 연결을 수락하기 전에 피어 주소를 확인할 수 있습니까?

나는 TCP 포트/소켓을 수신하고 연결을 받아들이는 간단한 Perl 서버를 작성했습니다. 이제 나는 알고 싶습니다:

주소 기반 접근 제어를 구현하려는 경우 연결을 수락하기 전에 연결을 요청하는 피어의 주소를 확인할 수 있습니까?

가능하다면 연결을 수락하고 즉시 다시 닫는 대신 연결 요청을 거부할 수 있습니다(희망합니다).

답변1

커널에 의해 TCP/IP 연결이 설정된 다음 해당 연결을 사용하여 애플리케이션이 시작됩니다.

원치 않는 연결을 필터링/차단하는 유일한 방법은 커널 방화벽을 사용하는 것입니다. 운영 체제를 지정하지 않았지만 Linux에서는 iptables/nftables가 됩니다.

답변2

실제로 답변은 아니지만 일부 의견이 너무 깁니다.

MacOS X에서는 다음과 man accept같이 말합니다.

msg_iovlen이 0이고 msg_controllen이 0이 아닌 상태에서 recvmsg(2) 호출을 실행하면 연결을 확인하지 않고도 사용자 연결 요청 데이터를 얻을 수 있습니다., 또는 getsockopt(2) 요청을 발행하여. 마찬가지로 제어 정보만 제공하는 sendmsg(2) 호출을 실행하거나 setockopt(2)를 호출하여 사용자 연결 거부 정보를 제공할 수 있습니다.

(강조는 내 것)

man recvmsg그러나 이 주제에 대한 자세한 내용을 찾을 수 없습니다 .man getsockoptman tcp

데비안에서는 man accept이렇게 말합니다:

소켓에서 들어오는 연결에 대한 알림을 받으려면 select(2), poll(2) 또는 epoll(7)을 사용하십시오. 새 연결이 시도되면 읽기 가능한 이벤트가 전달되고 그런 다음 accept()를 호출하여 해당 연결에 대한 소켓을 가져올 수 있습니다. 또는 소켓에서 활동이 발생할 때 SIGIO를 전달하도록 소켓을 설정할 수 있습니다. 자세한 내용은 Sockets(7)을 참조하세요.

IMHO, 거기엔 그거밖에 없어가능한더 많은 정보를 제공할 수 있으면 좋을 것 같습니다 epoll.

하지만 실제로 정보를 얻을 수 있다고 하더라도 마음에 들지 않으면 연결을 어떻게 거부할 것인지 잘 모르겠습니다.

네트워크 스택/방화벽 수준(iptables 및 친구)에서 필터링하는 것이 좋습니다.

답변3

나는 Perl에 대한 전문 지식이 있다고 주장하지 않습니다. 그러나 그것이 가능한지는 의심스럽습니다. 서버에 대한 액세스를 제어하기 위해 우선순위에 따라 다음을 제한합니다.

  1. 인터페이스/바인드 주소별
  2. 커널 방화벽(iptables, nftables, eBPF)을 통해
  3. TCP 래퍼 또는 호스트 구성을 통해

현재 호스트 구성을 통한 조절 기능이 없다는 점을 고려하면 이를 시작점으로 선택하는 것은 확실히 이례적인 것 같습니다.

위의 1과 2가 다음과 같다고 가정합니다.아니요한 가지 옵션은 Perl 코드에서 TCP 래퍼를 사용하는 것이 좋습니다. 이를 통해 유연하고 표준적이며 강력한 네트워크 액세스 제어 메커니즘을 활용하면서 최소한의 코드 변경으로 시작하고 실행할 수 있습니다. 당신은 또한 볼 수 있습니다https://metacpan.org/pod/Net::TCPwrappers

런타임에 LD_LIBRARY_PATH를 조정하여(즉, 코드 변경 없이) tcp 래퍼를 적용하는 것도 가능하다고 생각하지만 빠른 Google 검색에서는 이에 대한 참조를 찾을 수 없습니다.

답변4

전송 제어 프로토콜은 액세스 제어에 사용되지 않습니다.

TLS를 확인하는 것이 좋습니다https://en.m.wikipedia.org/wiki/Transport_Layer_Security

또한 netfilter 방화벽 입력 후크를 살펴보세요. 원치 않는 피어를 제거하고 거부할 수 있습니다.

관련 정보