netsat -tupn
내 Debian Jessie 서버의 출력은 다음과 같습니다.
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 10.0.0.12:445 10.0.0.20:49729 ESTABLISHED 26277/smbd
tcp 0 0 10.0.0.12:443 10.0.0.21:44162 ESTABLISHED 1400/nginx: worker
tcp 0 0 10.0.0.12:445 10.0.0.21:46650 ESTABLISHED 23039/smbd
tcp 0 0 10.0.0.12:443 10.0.0.20:54584 ESTABLISHED 1400/nginx: worker
tcp 0 0 10.0.0.12:139 10.0.0.225:10425 ESTABLISHED 23701/smbd
tcp 0 0 10.0.0.12:445 10.0.0.217:49179 ESTABLISHED 21535/smbd
tcp 0 0 10.0.0.12:445 10.0.0.217:49178 ESTABLISHED 21534/smbd
tcp 0 0 10.0.0.12:445 10.0.0.20:64636 ESTABLISHED 21470/smbd
tcp 0 0 10.0.0.12:443 10.0.0.21:44198 ESTABLISHED 1400/nginx: worker
tcp 0 0 10.0.0.12:2049 10.0.0.16:752 ESTABLISHED -
tcp 0 0 10.0.0.12:222 10.0.0.21:55514 ESTABLISHED 23111/sshd: redacted
tcp6 0 0 10.0.0.12:4243 10.0.0.20:64702 ESTABLISHED 31307/java
tcp6 0 0 10.0.0.12:48932 162.222.40.93:443 ESTABLISHED 31307/java
tcp6 0 0 10.0.0.12:49093 216.17.8.47:443 ESTABLISHED 31307/java
PID 31307 예충돌 계획백업 엔진, Java 버전 1.7.0_45
. 이 두 개의 비RFC1918 IPv4 주소는 CrashPlan의 서버이며 10.0.0.20:64702
클라이언트를 실행하는 컴퓨터이기도 합니다.
마지막 세 개의 연결이 IPv4 주소임에도 불구하고 tcp6으로 표시되는 이유는 무엇입니까?
답변1
이는 기본적으로 AF_INET6 소켓이 실제로 IPv4 및 IPv6 모두에서 작동하기 때문에 발생합니다. 바라보다섹션 3.7 - RFC 3493의 IPv4 노드와의 호환성 - IPv6용 기본 소켓 인터페이스 확장
다음은 이러한 상황을 생성할 수 있는 짧은 코드 예제입니다.
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define TEST_PORT 5555
#define xstr(s) str(s)
#define str(x) #x
int main (int argc, char **argv)
{
int v6server;
int v4client;
int rc;
struct sockaddr_in6 s6addr = {
.sin6_family = AF_INET6,
.sin6_flowinfo = 0,
.sin6_port = htons(TEST_PORT),
.sin6_addr = in6addr_any
};
struct sockaddr_in c4addr = {
.sin_family = AF_INET,
.sin_port = htons(TEST_PORT),
.sin_addr = inet_addr("127.0.0.1")
};
// Open an IPv6 listener
v6server = socket(AF_INET6, SOCK_STREAM, 0);
if (v6server < 0) perror("socket()");
rc = bind(v6server, (struct sockaddr *)&s6addr, sizeof(s6addr));
if (rc != 0) perror("bind()");
rc = listen(v6server, 0);
if (rc != 0) perror("listen()");
// Connect to the listener with an IPv4 socket
v4client = socket(AF_INET, SOCK_STREAM, 0);
if (v4client < 0) perror("socket()");
rc = connect(v4client, (struct sockaddr *)&c4addr, sizeof(c4addr));
if (rc != 0) perror("connect()");
// inspect open sockets
system("netstat -tan | grep " xstr(TEST_PORT));
close(v4client);
close(v6server);
}
내 Ubuntu 컴퓨터의 출력은 다음과 같습니다.
$ make v4v6
cc v4v6.c -o v4v6
$ ./v4v6
tcp 0 0 127.0.0.1:46518 127.0.0.1:5555 ESTABLISHED
tcp6 0 0 :::5555 :::* LISTEN
tcp6 0 0 127.0.0.1:5555 127.0.0.1:46518 ESTABLISHED
$
- 이
tcp6 LISTEN
항목은 포트 5555를 수신하는 소켓용입니다. 이는 AF_INET6 소켓이므로 IPv4 및 IPv6 수신 연결을 모두 허용합니다. - 이
tcp ESTABLISHED
항목은 AF_INET4 소켓을 리스너(활성 연결)에 연결한 결과입니다. - 이
tcp6 ESTABLISHED
항목은 리스너 소켓에서 생성된 수동 연결을 위한 것입니다. 이는 수신기에서 생성tcp6
되었기 때문에 나타나는 것처럼 보이지만 IPv4의 연결을 나타냅니다.tcp6
다음 사항에 주목할 가치가 있습니다.
- 이 동작은 AF_INET6 소켓에 특별합니다. AF_INET(IPv4) 소켓은 IPv6 콘텐츠를 전혀 처리할 수 없으며 앞으로도 처리하지 않습니다.
- 이 동작은 재정의될 수 있습니다.IPV6_V6ONLY 소켓 옵션. 이 옵션을 설정하면 소켓이오직IPv6을 처리하고 IPv4를 허용하지 않습니다.