소개
소켓은 서버에서 실행되는 프로그램 간 또는 별도의 서버에서 실행되는 프로그램 간 상호 프로세스 통신을 가능하게 하는 방법입니다. 서버 간 통신은 네트워크 소켓을 통해 이루어지며, 이는 인터넷 프로토콜 (IP)을 사용하여 데이터를 보내고 받는 데 사용됩니다.
클라이언트와 서버의 네트워크 소켓은 각각 소켓 주소로 참조됩니다. 주소는 전송 프로토콜인 전송 제어 프로토콜 (TCP) 또는 사용자 데이터그램 프로토콜 (UDP), IP 주소 및 포트 번호의 고유한 조합입니다.
이 튜토리얼에서는 프로세스간 통신에 사용되는 다음과 같은 다양한 유형의 소켓에 대해 알아보겠습니다:
- 스트림 소켓, 이들의 기본 전송 프로토콜로 TCP를 사용합니다.
- 데이터그램 소켓, 이들의 기본 전송 프로토콜로 UDP를 사용합니다.
- 유닉스 도메인 소켓, 네트워크 인터페이스와 IP 패킷 대신 로컬 파일을 사용하여 데이터를 보내고 받습니다.
이 튜토리얼의 각 섹션에서는 리눅스 시스템에서 각 소켓 유형을 나열하는 방법도 배우게 됩니다. 다양한 명령 줄 도구를 사용하여 각 소켓 유형을 조사할 것입니다.
필수 조건
이 자습서의 예제는 Ubuntu 20.04 서버에서 유효성을 검사했습니다. 배포판이 갖춰진 경우 로컬 컴퓨터 또는 원격 서버에서 대부분의 최신 Linux 배포판을 사용하여이 자습서를 따를 수 있습니다. 필요한 도구의 해당 버전이 각 배포판에 설치되어 있는 한입니다.
Ubuntu 20.04를 사용하기 위해 시작하려면 우리의 Ubuntu 20.04용 초기 서버 설정 가이드를 따라 구성된 서버가 하나 필요합니다.
또한 시스템의 패키지 캐시가 apt update
명령을 사용하여 최신 상태인지 확인하십시오:
그런 다음이 명령을 사용하여 필요한 패키지를 설치하십시오:
iproute2
패키지에는 소켓을 검사하는 데 사용되는 ss
유틸리티가 포함되어 있습니다. 우리는 netcat을 설치하기 위해 netcat-openbsd
패키지를 사용할 것입니다. 명령 줄에서 netcat은 nc
로 약식화됩니다. 마지막으로, 예제 소켓을 만들기 위해 socat
패키지를 사용할 것입니다.
스트림 소켓이란?
스트림 소켓은 연결 지향적이며, 이는 네트워크 소켓으로 전송되는 패킷이 응용 프로그램에 의해 처리되기 위해 호스트 운영 체제에 의해 전달된다는 것을 의미합니다. 네트워크 기반의 스트림 소켓은 일반적으로 네트워크 인터페이스를 통해 데이터를 캡슐화하고 전송하기 위해 전송 제어 프로토콜 (TCP)을 사용합니다.
TCP는 상태 기반 연결을 의존하는 신뢰할 수 있는 네트워크 프로토콜로 설계되었습니다. TCP 기반의 스트림 소켓을 사용하여 프로그램이 보낸 데이터는 원격 시스템에서 성공적으로 수신될 것입니다 (경로 지정, 방화벽 또는 기타 연결 문제가 없는 경우). TCP 패킷은 물리적 네트워크 인터페이스에 어떤 순서로든 도착할 수 있습니다. 패킷이 순서가 뒤바뀌어 도착하는 경우, 네트워크 어댑터와 호스트 운영 체제는 응용 프로그램이 처리할 수 있도록 올바른 순서로 재조립됨을 보장합니다.
A typical use for a TCP-based stream socket would be for a web server like Apache or Nginx handling HTTP requests on port 80
, or HTTPS on port 443
. For HTTP, a socket address would be similar to 203.0.113.1:80
, and for HTTPS it would be something like 203.0.113.1:443
.
TCP 기반 스트림 소켓 생성하기
다음 예제에서는 socat
(Socket Cat의 약자) 명령을 사용하여 대체 HTTP 포트인 포트 8080에서 HTTP 요청을 수신 대기하는 웹 서버를 흉내내고 있습니다. 그런 다음 ss
및 nc
명령을 사용하여 소켓을 검사할 것입니다.
먼저, IPv4 및 IPv6 인터페이스를 사용하여 포트 8080
에서 연결을 수신 대기하는 두 개의 TCP 기반 소켓을 생성하려면 다음과 같은 socat
명령을 실행하십시오:
TCP4-LISTEN:8080
및TCP6-LISTEN:8080
인수는 사용할 프로토콜 유형과 포트 번호입니다. 이들은socat
에게 모든 IPv4 및 IPv6 인터페이스의 포트8080
에서 TCP 소켓을 생성하고 각 소켓에서 들어오는 연결을 수신하도록 알려줍니다.socat
은 시스템에서 사용 가능한 모든 포트에서 수신 대기할 수 있으므로 소켓 옵션에는0
에서65535
까지의 모든 포트가 유효한 매개변수입니다.fork
옵션은 연결 처리 후에도socat
이 계속 실행되도록합니다. 그렇지 않으면 자동으로 종료됩니다./dev/null
경로는 원격 소켓 주소 대신 사용됩니다. 이 경우에는socat
에게 들어오는 입력을/dev/null
파일에 인쇄하도록 지시하여 입력을 음소거합니다.ipv6only=1
플래그는 IPv6 소켓에 대해 사용되며 소켓이 IPv4-mapped IPv6 주소로 패킷을 보낼 수 없도록 운영 체제에 알려줍니다. 이 플래그가 없으면socat
은 IPv4 및 IPv6 주소에 바인딩됩니다.&
문자는 셸에게 명령을 백그라운드에서 실행하도록 지시합니다. 이 플래그는 소켓을 검사하기 위해 다른 명령을 호출하는 동안socat
이 계속 실행되도록합니다.
다음과 같은 출력을 받게됩니다. 이는 셸 세션에서 백그라운드로 실행되는 두 개의 socat
프로세스 ID를 나타냅니다. 여러분의 프로세스 ID는 여기 강조된 것과 다를 것입니다:
Output[1] 434223
[2] 434224
이제 백그라운드에서 TCP 포트 8080
에서 듣는 두 개의 socat
프로세스가 있으므로 ss
및 nc
유틸리티를 사용하여 소켓을 검사할 수 있습니다.
TCP 기반 스트림 소켓 검사
모던한 리눅스 시스템에서 ss
명령어를 사용하여 TCP 소켓을 검사하려면 다음 플래그를 사용하여 실행하십시오:
-4
및-6
플래그는 각각 IPv4 또는 IPv6 소켓만 검사하도록ss
에게 알려줍니다. 이 옵션을 생략하면 두 종류의 소켓이 모두 표시됩니다.t
플래그는 출력을 TCP 소켓으로 제한합니다. 기본적으로ss
도구는 리눅스 시스템에서 사용되는 모든 유형의 소켓을 표시합니다.l
플래그는 출력을 수신 대기 소켓으로 제한합니다. 이 플래그가 없으면 SSH, 웹 서버에 연결된 클라이언트 또는 시스템이 다른 서버에 대한 연결과 같은 모든 TCP 연결이 표시됩니다.n
플래그는 서비스 이름 대신 포트 번호가 표시되도록 합니다.
먼저 시스템에서 연결을 기다리는 IPv4 TCP 소켓을 검사하려면 다음과 같이 ss -4 -tln
명령을 실행하십시오:
다음과 같은 출력이 표시됩니다:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
LISTEN 0 1 0.0.0.0:8080 0.0.0.0:*
. . .
출력에는 시스템에서 실행 중인 서비스에 따라 다른 포트를 사용하는 다른 줄이 있을 수 있습니다. 출력의 강조된 0.0.0.0:8080
부분은 IPv4 TCP 소켓이 포트 8080
에서 모든 사용 가능한 IPv4 인터페이스에서 수신 대기 중임을 나타냅니다. 특정 IPv4 주소에서만 수신 대기 중인 서비스는 강조된 필드에 해당 IP만 표시됩니다. 예를 들어 203.0.113.1:8080
입니다.
이제 동일한 ss
명령을 -6
플래그와 함께 다시 실행하십시오:
다음과 같은 출력을 받게됩니다:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
LISTEN 0 5 [::]:8080 [::]:*
. . .
시스템에서 실행 중인 서비스에 따라 출력에 다른 포트를 사용하는 다른 줄이 있을 수 있습니다. 출력의 강조된 [::]:8080
부분은 IPv6 TCP 소켓이 포트 8080
에서 모든 사용 가능한 IPv6 인터페이스에서 수신 대기 중임을 나타냅니다 (::
문자는 모든 값이 0으로 구성된 주소를 나타내는 IPv6 표기법입니다). 특정 IPv6 주소에서만 수신 대기 중인 서비스는 강조된 필드에 해당 IP만 표시됩니다. 예를 들어 [2604:a880:400:d1::3d3:6001]:8080
입니다.
TCP 기반 스트림 소켓에 연결
지금까지 IPv4 및 IPv6 인터페이스에서 TCP 소켓을 생성하고 열거하는 방법을 배웠습니다. 이제 연결을 수립하기 위해 netcat 유틸리티를 사용하여 소켓에 연결하는 실험을 할 수 있습니다.
로컬 및 원격 소켓에 대한 TCP 연결을 테스트하기 위해 netcat을 사용하는 것은 시스템 간의 연결 및 방화벽 문제를 격리하는 데 도움이 되는 매우 유용한 문제 해결 기술입니다.
netcat을 사용하여 로컬 루프백 주소를 통해 IPv4 소켓에 연결하려면 다음 명령을 실행하십시오:
-4
플래그는 netcat이 IPv4를 사용하도록 지시합니다.-v
플래그는 자세한 출력을 터미널에 인쇄하기 위해 사용됩니다.- –
z
옵션은 netcat이 데이터를 보내지 않고 소켓에만 연결하도록합니다. - 로컬 루프백
127.0.0.1
IP 주소는 시스템이 고유한 IP 주소를 가지고 있기 때문에 사용됩니다. 시스템의 IP를 알고 있다면 해당 IP를 사용하여 테스트할 수도 있습니다. 예를 들어 시스템의 공용 또는 사설 IP 주소가 203.0.113.1이면 루프백 IP 대신에 사용할 수 있습니다.
다음과 같이 출력을 받게 됩니다:
OutputConnection to 127.0.0.1 (127.0.0.1) 8080 port [tcp/http-alt] succeeded!
강조된 줄은 netcat의 출력입니다. 이는 netcat이 루프백 127.0.0.1
IPv4 주소의 포트 8080
에서 수신 대기중인 TCP 소켓에 연결했음을 나타냅니다. 두 번째 줄은 무시해도 됩니다. 이것은 백그라운드에서 실행 중인 터미널 내의 socat 프로세스에서 온 것입니다.
이제 IPv6를 사용하여 동일한 연결 테스트를 반복할 수 있습니다. 다음 netcat 명령을 실행하십시오:
다음과 같은 출력을 받아야 합니다:
OutputConnection to ::1 8080 port [tcp/http] succeeded!
강조된 줄은 netcat의 출력입니다. 이는 netcat이 루프백 ::1
IPv6 주소의 포트 8080
에서 수신 대기중인 TCP 소켓에 연결했음을 나타냅니다. 다시 한 번 출력의 두 번째 줄은 무시해도 됩니다.
소켓을 정리하려면 생성한 각 socat 프로세스에 대해 fg
(foreground) 명령을 실행해야 합니다. 그런 다음 각 socat을 닫기 위해 CTRL+C
를 사용합니다. fg
는 터미널의 전경으로 프로세스를 가져오는데, 실행한 순서의 역순으로 실행됩니다. 따라서 실행하면 두 번째 socat
인스턴스가 먼저 상호 작용할 인스턴스가 됩니다.
두 번째 IPv6 socat 인스턴스를 터미널의 전경으로 가져 오려면 fg
를 실행하십시오. 그런 다음 CTRL+C
를 실행하여 닫으십시오.
다음과 같은 출력을 받게 됩니다:
Outputsocat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null
프로세스를 중지하려면 CTRL+C
를 누르세요.
이제 fg
를 다시 실행하여 첫 번째 IPv4 소켓을 정리하십시오. 다음과 같은 출력이 있어야 합니다:
Outputsocat TCP4-LISTEN:8080,fork /dev/null
프로세스를 중지하려면 CTRL+C
를 누르세요.
이제 시스템에서 IPv4 및 IPv6 소켓을 생성, 확인 및 연결했습니다. 이러한 기술과 도구는 로컬 개발 시스템 또는 원격 프로덕션 서버에서 작동하므로 각 도구를 실험하여 TCP 소켓을 테스트하고 문제 해결하는 방법에 익숙해지십시오.
데이터그램 소켓이란?
데이터그램 소켓은 연결이 없으며, 즉 소켓에서 보내고 받은 패킷은 애플리케이션에 의해 개별적으로 처리됩니다. 네트워크 기반 데이터그램 소켓은 일반적으로 데이터를 캡슐화하고 전송하기 위해 사용자 데이터그램 프로토콜 (UDP)을 사용합니다.
UDP 패킷 헤더에는 순서 정보가 인코딩되지 않으며, 프로토콜에 오류 수정 기능이 내장되어 있지 않습니다. 데이터그램 기반 네트워크 소켓을 사용하는 프로그램은 성공적인 데이터 전송을 보장하기 위해 자체 오류 처리 및 데이터 순서 지정 논리를 구축해야 합니다.
UDP 소켓은 주로 도메인 이름 시스템 (DNS) 서버에서 사용됩니다. DNS 서버는 기본적으로 도메인 이름에 대한 쿼리를 보내고 받기 위해 포트 53
을 사용합니다. DNS 서버의 예시 UDP 소켓 주소는 다음과 유사할 수 있습니다: 203.0.113.1:53
.
참고: 프로토콜은 소켓 주소의 사람이 읽을 수 있는 버전에 포함되어 있지 않지만, 운영 체제는 주소의 일부로 TCP 및 UDP 프로토콜을 포함하여 소켓 주소를 구별합니다. 따라서 203.0.113.1:53
과 같은 사람이 읽을 수 있는 소켓 주소는 두 프로토콜 중 하나를 사용할 수 있습니다. ss
와 이전 netstat
유틸리티와 같은 도구를 사용하여 사용되는 소켓의 종류를 확인합니다.
네트워크 시간 프로토콜(NTP)은 컴퓨터간의 시계 동기화를 위해 포트 123
의 UDP 소켓을 사용합니다. NTP 프로토콜의 예시 UDP 소켓은 다음과 같을 수 있습니다: 203.0.113.1:123
.
데이터그램 소켓 생성
이전의 TCP 소켓 예제와 마찬가지로, 이 섹션에서는 다시 socat
을 사용하여 UDP 포트 123
에서 요청을 수신하는 NTP 서버를 흉내 내게 됩니다. 그런 다음 ss
및 nc
명령을 사용하여 생성하는 소켓을 검사하게 됩니다.
먼저 다음과 같은 socat
명령을 실행하여 IPv4 및 IPv6 인터페이스에서 연결을 수신하는 두 개의 UDP 소켓을 생성합니다:
다음과 같은 출력을 받게 될 것입니다. 이는 셸 세션의 백그라운드에서 실행되는 두 개의 socat
프로세스 ID를 나타냅니다. 여기에 강조된 것과는 다른 프로세스 ID를 가지게 됩니다:
Output[1] 465486
[2] 465487
- 모든 명령은 대부분의 시스템에서 예약되어 있는 포트
0
에서1024
까지를 사용하기 때문에sudo
로 접두어가 붙습니다.sudo
는 관리자 권한으로 명령을 실행하여socat
이 예약된 범위 내의 모든 포트에 바인딩할 수 있도록합니다. UDP4-LISTEN:123
및UDP6-LISTEN:123
인수는 프로토콜 유형 및 포트를 지정합니다. 이것들은 socat에게 IPv4 및 IPv6 인터페이스의 포트123
에서 UDP 기반 소켓을 생성하고 들어오는 데이터를 수신하도록 알려줍니다. 다시 말해, 0-65535의 전체 범위 내의 어떤 포트도 UDP 소켓에 대한 유효한 매개변수입니다.fork
,ipv6only=1
, 및/dev/null
인수는 이전 TCP 예제에서 설명한 것과 동일한 방식으로 사용됩니다.
이제 UDP 포트 123
에서 수신 대기 중인 두 개의 socat
프로세스가 있으므로 ss
및 nc
유틸리티를 사용하여 소켓을 검사할 수 있습니다.
데이터그램 소켓 검사
현대 Linux 시스템에서 ss
명령을 사용하여 UDP 소켓을 검사하려면 다음과 같은 -4
, -6 및
uln` 플래그를 사용하여 출력을 제한하십시오:
u
플래그는 출력을 UDP 소켓으로 제한합니다. 다른 플래그들은 이전 TCP 예제에서 사용한 것과 동일합니다.
먼저 시스템에서 연결을 대기 중인 IPv4 UDP 소켓을 검사하려면 ss -4 -uln
명령을 실행하십시오:
다음과 같은 출력을 받게 됩니다:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
. . .
시스템에서 실행 중인 서비스에 따라 출력에 다른 포트가 있는 경우가 있을 수 있습니다. 강조된 출력의 0.0.0.0:123
부분은 IPv4 UDP 소켓이 포트 123
에서 모든 IPv4 인터페이스에서 사용 가능하다는 것을 나타냅니다. 특정 IPv4 주소에서만 사용 가능한 서비스의 경우 강조된 필드에 해당 IP만 표시됩니다. 예를 들어 203.0.113.1:123
입니다.
이제 동일한 ss
명령을 -6
플래그와 함께 다시 실행하십시오:
다음과 같은 출력을 받게 됩니다:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
UNCONN 0 0 [::]:123 [::]:*
. . .
시스템에서 실행 중인 서비스에 따라 출력에 다른 포트를 사용하는 다른 라인이 있을 수 있습니다. 출력의 강조된 [::]:123
부분은 IPv6 TCP 소켓이 모든 IPv6 인터페이스에서 포트 123
에 사용 가능하다는 것을 나타냅니다 (::
문자로 표시됨). 특정 IPv6 주소에서만 사용 가능한 서비스는 강조된 필드에 해당 IP만 표시됩니다. 예를 들어, [2604:a880:400:d1::3d3:6001]:123
.
데이터그램 소켓 테스트
이제 IPv4 및 IPv6 인터페이스에서 UDP 소켓을 생성하고 열거하는 방법을 알게 되었으므로 이에 연결해보실 수 있습니다. TCP 소켓과 마찬가지로 netcat 유틸리티를 사용하여 UDP 소켓을 실험할 수 있습니다.
이 튜토리얼의 이전 섹션에서 만든 포트 123
의 예제 UDP 소켓에 연결하려면 다음 netcat 명령을 실행하십시오:
-4
플래그는 netcat이 IPv4를 사용하도록 지시합니다.-u
옵션은 netcat이 TCP가 아닌 UDP를 사용하도록 지시합니다.-v
플래그는 자세한 출력을 터미널에 인쇄하는 데 사용됩니다.-z
옵션은 netcat이 데이터를 보내지 않고 소켓에만 연결하도록합니다.- 로컬 루프백
127.0.0.1
IP 주소는 시스템이 고유한 IP 주소를 가지고 있기 때문에 사용됩니다. 시스템의 IP를 알고 있다면 해당 IP를 사용하여 테스트할 수도 있습니다. 예를 들어, 시스템의 공용 또는 사설 IP 주소가203.0.113.1
인 경우 루프백 IP 대신 사용할 수 있습니다.
다음과 같은 출력을 받게 됩니다:
OutputConnection to 127.0.0.1 123 port [udp/ntp] succeeded!
출력은 루프백 127.0.0.1
IPv4 주소의 포트 123
에서 수신 대기 중인 UDP 소켓으로부터 netcat이 오류를 받지 않았음을 나타냅니다. 이러한 오류 응답의 부재는 소켓이 127.0.0.1:123
에서 사용 가능하다는 것을 추론하는 데 사용됩니다. 이 동작은 TCP 소켓과 다르며, TCP 소켓은 소켓이 사용 가능한지 여부를 확인하기 위해 패킷을 교환해야 합니다.
참고: 이 예제에서 소켓이 사용 불가능한 경우 원격 시스템은 포트가 원격 호스트에서 접근할 수 없음을 나타내는 ICMP 유형 3 메시지 (도착지 불가능)와 코드 3을 반환합니다.
오류 응답이 없는 것을 바탕으로 소켓이 사용 가능하다고 추론하는 것은 ICMP 트래픽을 차단하는 방화벽이나 연결 문제가 없다고 가정합니다. UDP 소켓을 통해 응용 프로그램 데이터를 보내고 수신하고 확인하지 않으면 원격 UDP 포트가 열려 있고 패킷을 수신하는지에 대한 보장이 없습니다.
이제 동일한 연결 테스트를 IPv6를 사용하여 반복할 수 있습니다. 다음 netcat 명령을 실행하십시오:
다음과 같은 출력을 받아야 합니다:
OutputConnection to ::1 123 port [udp/ntp] succeeded!!
출력은 루프백 주소인 IPv6 주소 ::1
의 포트 123
에서 수신 된 UDP 소켓에서 오류를 받지 않았음을 나타냅니다. 다시 말해, 이 오류 응답 부재는 ::1:123
소켓이 사용 가능하다는 것을 추론하는 데 사용됩니다.
소켓을 정리하려면 생성 한 각 socat 프로세스에 대해 fg
(전경) 명령을 실행해야합니다. 그런 다음 각 socat을 닫으려면 CTRL+C
를 사용합니다.
두 번째 IPv6 socat
인스턴스를 터미널의 전경으로 가져 오려면 fg
를 실행하십시오. 그런 다음 CTRL+C
를 사용하여 닫으십시오.
다음과 같은 출력이 표시됩니다:
Outputsudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null
프로세스를 중지하려면 CTRL+C
를 누르십시오.
이제 첫 번째 IPv4 소켓을 정리하려면 다시 fg
를 실행하십시오. 다음과 같은 출력이 나옵니다:
Outputsudo socat UDP4-LISTEN:123,fork /dev/null
프로세스를 중지하려면 CTRL+C
를 누르십시오.
이제 시스템에서 IPv4 및 IPv6 UDP 소켓을 생성, 검사 및 테스트했습니다. 각 도구를 실험하여 UDP 소켓을 테스트하고 문제 해결하는 방법에 대해 더 익숙해지십시오.
Unix 도메인 소켓이란?
동일한 서버에서 실행되는 프로그램들은 Unix 도메인 소켓 (UDS)을 사용하여 서로 통신할 수도 있습니다. Unix 도메인 소켓은 스트림 기반일 수도 있고, 데이터그램 기반일 수도 있습니다. 도메인 소켓을 사용할 때 데이터는 호스트 파일 시스템의 파일을 통해 운영 체제의 커널에서 프로그램들 간에 직접 교환됩니다. 도메인 소켓을 사용하여 데이터를 보내거나 받으려면 프로그램들은 네트워크 기반 소켓과 프로토콜을 완전히 우회하여 공유 소켓 파일로 읽고 쓰기를 합니다.
Unix 도메인 소켓은 네트워크 인터페이스에 연결되지 않은 데이터베이스 시스템에서 널리 사용됩니다. 예를 들어, Ubuntu에서 MySQL은 로컬 클라이언트와의 통신에 /var/run/mysqld/mysql.sock
이라는 파일을 기본으로 사용합니다. 클라이언트는 소켓에서 읽고 쓰며, MySQL 서버 자체도 마찬가지입니다.
또 다른 데이터베이스 시스템으로는 PostgreSQL이 있으며, 로컬 비네트워크 통신을 위해 소켓을 사용합니다. 일반적으로 소켓 파일로 /run/postgresql/.s.PGSQL.5432
를 기본값으로 사용합니다.
Unix 도메인 소켓 생성하기
이전 섹션에서는 TCP가 스트림 소켓과 함께 사용되는 방법과 UDP가 데이터그램 소켓과 함께 사용되는 방법을 탐구했습니다. 이번 섹션에서는 네트워크를 통해 보낼 데이터를 캡슐화하기 위해 TCP 또는 UDP를 사용하지 않고도 스트림 기반 및 데이터그램 기반 Unix 도메인 소켓을 생성하기 위해 socat
을 사용합니다. 그런 다음 ss
및 nc
명령을 사용하여 생성한 소켓을 검사합니다. 마지막으로 netcat을 사용하여 Unix 도메인 소켓을 테스트하는 방법에 대해 배우게 됩니다.
시작하려면 다음 socat
명령을 실행하여 두 개의 소켓 파일을 생성하십시오:
- 첫 번째 명령은 스트림 기반 UDS를 생성할
unix-listen
주소 유형을 사용하여 소켓을 생성하도록 socat에 지시합니다. - 두 번째 명령은 소켓 유형으로
unix-recvfrom
을 지정하며 데이터그램 기반 UDS를 생성합니다. - 두 명령 모두
:
구분자 뒤에 파일 이름을 지정합니다. 파일 이름은 소켓 자체의 주소입니다. 첫 번째 스트림 예제의 경우/tmp/stream.sock
이고 두 번째 데이터그램 예제의 경우/tmp/datagram.sock
입니다. 소켓의 이름은 임의로 지정되지만 문제 해결시 설명적인 것이 도움이 됩니다. fork
및/dev/null
인수는 스트림 및 데이터그램 소켓 예제 섹션에서 설명한 대로 동일하게 사용됩니다.
이제 두 개의 UDS 소켓을 생성했으므로 ss
및 nc
유틸리티를 사용하여 검사할 수 있습니다.
유닉스 도메인 소켓 검사
모든 수신 대기 중인 유닉스 도메인 소켓을 나열하려면 ss -xln
명령을 실행하십시오. x
플래그는 도메인 소켓만 표시되도록합니다.
다음과 같은 출력을 받게됩니다:
OutputNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
u_str LISTEN 0 5 /tmp/stream.sock 436470 * 0
u_dgr UNCONN 0 0 /tmp/datagram.sock 433843 * 0
. . .
다음의 /tmp/stream/sock
줄의 강조된 u_str
부분에 유의하십시오. 이 필드는 소켓 유형이 스트림 기반 UDS임을 나타냅니다. 두 번째 줄은 유형이 u_dgr
이며 이는 소켓 유형이 데이터그램 기반임을 의미합니다.
유닉스 도메인 소켓은 파일이므로 일반적인 리눅스 사용자 및 그룹 권한 및 액세스 제어를 사용하여 소켓에 연결할 수 있는 사용자를 제한할 수 있습니다. 또한 ls
, mv
, chown
, chmod
와 같은 파일 시스템 도구를 사용하여 UDS 파일을 검사하고 조작할 수 있습니다. SELinux와 같은 도구를 사용하여 다른 보안 컨텍스트로 UDS 파일에 라벨을 지정할 수도 있습니다.
파일이 UDS 소켓인지 확인하려면 ls
, file
또는 stat
유틸리티를 사용하십시오. 그러나 이러한 도구 중 어느 것도 UDS가 스트림인지 데이터그램 기반인지를 판별할 수 없다는 점을 유의하십시오. 유닉스 도메인 소켓에 대한 가장 완벽한 정보를 얻으려면 ss
도구를 사용하십시오.
파일 시스템에서 소켓을 검사하려면, stat
유틸리티가 가장 관련있는 정보를 보여줍니다. 이전에 만든 소켓에 대해 실행하십시오:
Output File: /tmp/stream.sock
Size: 0 Blocks: 1 IO Block: 131072 socket
Device: 48h/72d Inode: 1742 Links: 1
Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:22:42.678231700 +0000
Birth: -
File: /tmp/datagram.sock
Size: 0 Blocks: 1 IO Block: 131072 socket
Device: 48h/72d Inode: 1743 Links: 1
Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:10:25.025755168 +0000
Birth: -
각 파일에 대해 출력을 다음과 같이 받게 됩니다: socket
유형 (출력의 가장 오른쪽에 강조 표시됨)과 접근 모드에는 파일 권한 앞에 s
문자가 포함됩니다.
ls
유틸리티는 또한 파일이 소켓인지 여부를 나타냅니다. 파일을 조사하려면 ls -l
을 실행하세요:
다음과 같은 출력을 받게됩니다. 다시 한번 소켓의 경우, 파일 모드에는 파일 권한 필드 앞에 s
문자가 포함되어 있음에 유의하십시오:
Outputsrwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/datagram.sock
srwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/stream.sock
이제 Unix 도메인 소켓을 생성하고 ss
및 다양한 파일 시스템 기반 도구를 사용하여 이를 조사하는 방법을 배웠으므로 다음 단계는 netcat과 같은 도구를 사용하여 소켓을 테스트하는 것입니다.
Unix 도메인 소켓 테스트
netcat 유틸리티는 이전 튜토리얼에서 이미 배운 TCP 및 UDP 소켓뿐만 아니라 Unix 도메인 소켓에 연결하는 데 사용할 수 있습니다. 생성한 예제 소켓에 연결하려면 netcat 명령을 실행할 때 추가로 -U
플래그를 지정해야 합니다. 이 플래그는 netcat이 TCP 또는 UDP 기반 네트워크 소켓이 아닌 UDS에 연결하도록 지시합니다.
또한, 소켓이 데이터그램 기반인 경우, 이 튜토리얼의 데이터그램 소켓 섹션에서 배운 대로 netcat을 사용하여 데이터그램을 사용하도록 -u
플래그를 사용합니다.
UDS 소켓을 검사하기 시작하겠습니다. 다음 명령어로 스트림 기반 소켓에 연결합니다:
-U
는 netcat이 Unix 도메인 소켓에 연결하고 있음을 나타냅니다. -z
옵션은 netcat이 데이터를 전송하지 않고 소켓에만 연결하도록합니다. /tmp/stream.sock
은 파일 시스템상의 소켓 주소입니다.
명령어를 실행할 때 netcat에서는 출력을 받지 않습니다. 그러나 소켓이 없는 경우 다음과 같은 오류 메시지가 출력됩니다:
Outputnc: unix connect failed: No such file or directory
nc: /tmp/stream.sock: No such file or directory
따라서 스트림 기반 UDS 소켓을 테스트할 때 netcat에서 출력이 없으면 연결이 성공한 것입니다.
이번에는 데이터그램 기반 UDS에 대해 테스트 프로세스를 반복합니다:
추가적으로 -u
플래그를 추가하여 원격 소켓이 데이터그램 소켓임을 netcat에 알려줍니다. 다시 한 번 테스트가 성공하면 출력을 받지 않습니다.
주소에 소켓이 없는 경우 다음과 같은 오류를 받게됩니다:
Outputnc: unix connect failed: No such file or directory
nc: /tmp/datagram.sock: No such file or directory
소켓을 정리하려면 생성한 각 socat 프로세스에 대해 fg
(포그라운드) 명령을 실행해야합니다. 그런 다음 각 socat을 닫기 위해 CTRL+C
를 사용합니다.
데이터그램 기반 socat
인스턴스를 터미널의 전경으로 가져오려면 fg
를 실행합니다:
다음과 같은 출력을 받게됩니다:
Outputsocat unix-recvfrom:/tmp/datagram.sock,fork /dev/null
닫으려면 CTRL+C
를 실행합니다. 출력을 받지 않습니다.
이제 첫 번째 스트림 기반 UDS 소켓을 정리하기 위해 다시 fg
를 실행합니다:
다시 다음과 같은 출력을 받아야합니다:
Outputsocat unix-listen:/tmp/stream.sock,fork /dev/null
프로세스를 종료하려면 CTRL+C
를 실행하십시오. 출력을 받지 않습니다.
이제 시스템에서 Unix 데이터그램 소켓을 만들고 검사하고 테스트했습니다. netcat 및 socat
을 사용하여 UDS(UNIX 도메인 소켓)를 통해 데이터를 송수신하고 테스트하고 문제를 해결하는 방법에 대해 더 익숙해지려고 해보십시오.
결론
이 자습서에서는 Linux 시스템에서 다양한 종류의 소켓이 사용되는 방법을 살펴보았습니다. 네트워크 통신에 일반적으로 TCP를 사용하는 스트림 기반 소켓과 네트워크로 데이터를 전송하기 위해 UDP를 사용하는 데이터그램 기반 소켓에 대해 배웠습니다. 마지막으로 로컬 서버에서 Unix 도메인 소켓이 스트림 또는 데이터그램 기반일 수 있는 방법에 대해 알아보았습니다.
각 섹션에서는 Linux 시스템에서 소켓에 대한 정보를 수집하기 위해 ss
유틸리티를 사용했습니다. ss
도구가 제공하는 다른 플래그가 시스템에서 소켓을 검사할 때 출력을 특정 유형의 소켓으로 제한하는 데 어떻게 도움이 되는지 배웠습니다.
마침내이 자습서에서 논의된 세 가지 다른 유형의 소켓을 만들고 연결하기 위해 netcat 및 socat
도구를 사용했습니다. netcat 유틸리티는 소켓에 연결하는 데 널리 사용되지만 소켓을 생성할 수도 있습니다. 그 사용 설명서 (man nc
)에는 두 가지 모드 중 어떻게 사용할 수 있는지에 대한 많은 예가 포함되어 있습니다. socat
유틸리티는 이 자습서에서 다루지 않은 여러 가지 다른 유형의 소켓에 연결할 수 있는 고급 도구입니다. 해당 문서 (man socat
)에는 다양한 사용 방법에 대한 많은 예가 포함되어 있습니다.
소켓이 무엇이며 어떻게 작동하는지 이해하는 것은 핵심 시스템 관리 기술입니다. 이 자습서에서 실험한 도구와 기술은 소켓에 더 익숙해지고 서버와 응용 프로그램이 올바르게 통신하지 않을 때 문제를 해결하는 데 도움이 될 것입니다.
Source:
https://www.digitalocean.com/community/tutorials/understanding-sockets