FreeBind 대 After=: systemd 소켓을 VPN 주소에 바인딩하기
FreeBind는 VPN 주소가 생기기 전에 systemd가 리스너를 소유하게 하고, After=는 작업 순서만 정합니다. 둘을 비교한 뒤 순서와 준비 상태를 시험하세요.
부팅 시 고정 VPN 주소에 바인딩하는 소켓 유닛은 터널이 그 주소를 할당하기 전에 실패할 수 있고, 그 뒤의 서비스는 결코 시작되지 않습니다. 두 스위치는 수정처럼 보이지만 그 문제의 서로 다른 절반을 해결합니다. FreeBind는 주소가 아직 없을 때 systemd가 리스너를 만들게 합니다. After=는 작업 순서만 정하므로 무엇이 언제 시작되는지는 바꾸지만 주소를 더 빨리 도착하게 하지는 않습니다.
두 가지 다른 문제, 두 가지 다른 스위치
첫 번째 문제는 바인딩 실패입니다. 커널은 호스트가 소유하지 않은 주소에서의 수신을 거부하므로 소켓 유닛이 즉시 실패하고 서비스는 결코 활성화되지 않습니다. 두 번째 문제는 준비 상태 실패입니다. 주소는 결국 존재하지만, 터널이 트래픽을 실어 나르기 전에 무언가가 그것을 사용하려 합니다. FreeBind는 첫 번째를 다루고 두 번째에는 아무것도 하지 않습니다. 순서 지시자는 어느 쪽도 직접 다루지 않습니다.무엇이 어떤 순서로 시작하는지만 결정하기 때문입니다. 실제로 가진 실패를 명명하는 것이 결정의 전부입니다.
둘 중 어느 것인지는 서비스 설명이 아니라 저널에서 확인하세요. 바인딩 실패는 주소를 지목하고 할당할 수 없다고 보고합니다. 준비 상태 실패는 보통 더 나중에 나타나며, 시간 초과나 반대편에서 본 거부된 연결의 형태로 나타나고, 로그에는 완전히 건강한 소켓 유닛이 남습니다.
FreeBind: 리스너는 주소보다 먼저 존재한다
FreeBind는 커널에 비로컬 주소로의 바인딩을 허용하라고 말하므로, systemd는 부팅 시 수신 소켓을 만들고 애플리케이션이 시작될 때마다 그것을 애플리케이션에 넘길 수 있습니다. 이것이 소켓 활성화의 요점이며, 소켓이 뒤의 서비스보다 오래 살 수 있는 이유입니다.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
빈 할당은 새 항목을 추가하기 전에 벤더 유닛에서 상속된 수신 항목을 지우며, 이는 남은 와일드카드 리스너가 모든 인터페이스에서 응답하는 것을 막습니다. 주소와 포트를 자신의 것으로 바꾸고 drop-in 파일만이 아니라 유효 유닛을 확인하세요. 패키지 파일을 그 자리에서 편집하는 대신 유닛 이름 아래 drop-in을 사용하세요. 다음 패키지 업데이트가 편집을 덮어써 의도의 흔적을 남기지 않기 때문입니다. 그다음 소켓 유닛이 기대하는 재로드 및 재시작 절차로 적용하세요.
systemd 소켓 참조는 이 옵션 뒤의 IPv4 및 IPv6 동작을 문서화하며, 중요한 세부 사항은 이것이 라우팅이 아니라 바인딩에 적용된다는 점입니다. 그 안에서 주소를 할당하거나 VPN을 시작하는 것은 없습니다. FreeBind는 리스너에게 주어진 허가이며 인터페이스의 대체물이 아닙니다.
After=와 Wants=: 순서는 준비 상태가 아니다
순서와 요구는 별개의 축이며, 둘을 혼동하면 올바른 순서로 시작하고도 실패하는 유닛이 만들어집니다.After=vpn-client.service는 두 작업이 모두 시작되면 이쪽이 다른 쪽의 시작을 기다린다는 뜻일 뿐입니다. VPN을 끌어오지 않고, VPN의 연결 완료도 기다리지 않습니다.
Wants=나Requires=같은 요구 지시자는 활성화를 처리하며, 의존성이 실패할 때의 동작이 다릅니다. 하나는 계속하고 다른 하나는 멈춥니다. 어느 것도 연결된 터널이 무엇을 뜻하는지 모릅니다. VPN 프로세스는 주소가 할당되지 않은 채로도, 주소는 있지만 피어로 가는 경로가 없어도 활성일 수 있고, 두 상태 모두 의존성을 만족합니다. 애플리케이션에 주소의 존재가 필요하다면, 프로세스 시작을 준비의 증거로 삼지 말고 그 조건을 명시적으로 모델링하세요.
systemctl cat와systemctl show -p After -p Wants -p Requires로 유닛이 실제로 무엇을 선언하는지 확인하세요. 세 개의 다른 디렉터리에 있는 drop-in이 작성한 적 없는 지시자를 추가할 수 있으며, systemd는 유효 유닛만 읽습니다.
network-online.target이 하지 않는 일
network-online.target뒤에 정렬된 유닛은 네트워크 관리자가 네트워크를 사용 가능하다고 선언하기를 기다리며, 이는 부팅 시점의 동기화 지점이고 지속적인 조건이 아닙니다. 특정 터널이 올라와 있는지는 말하지 않으며, 오후에 VPN이 다시 연결될 때 다시 발동하지도 않습니다. 이것을 재연결 감시자로 보는 것이 그 대상의 가장 흔한 오독입니다.
systemd 프로젝트는 그 차이를 직접 문서화하며, 실무적 결과는 터널 주소가 필요한 모든 것이 의존성을 스스로 가져야 한다는 것입니다. network-online을 기다린 뒤 터널 주소를 바인딩하는 유닛은 터널이 우연히 먼저 올라올 때만 옳고, 그것은 설계가 아니라 우연입니다.
실제로 선택한 수명 주기를 시험하세요
깨끗한 부팅, 주소가 나타난 뒤의 요청, VPN이 끊겼다가 돌아온 뒤의 동작을 시험하세요. 이 세 경우가 동작하는 리스너와 동작하는 서비스를 구분합니다.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
첫 명령은 재시작 전에 유닛 파일 오류를 잡고, 둘째는 병합된 유닛을 보여 주며, 셋째는 리스너가 존재하는지 어느 주소에 있는지 증명합니다. 터널 주소를 기대한 곳에서 와일드카드 주소의 리스너가 있는 것은 빈 ListenStream이 제거하려 했던 바로 그 잔재입니다. 주소가 옮겨졌는지 보려면 VPN 재연결 뒤에 셋째 명령을 반복하세요.
수명 주기를 의도적으로 고르세요. 안정적인 주소가 돌아오기를 기다리는 자유 바인딩 리스너이거나, 터널과 함께 멈추고 복구 시 다시 시작하는 서비스입니다. 이들은 다른 설계이고 다른 방식으로 실패합니다. 그런 다음 접근 정책을 의도한 원본과 경로에 묶어 두세요. 목적지 주소를 바인딩해도 수락된 패킷이 신뢰할 수 있는 인터페이스로 도착했음이 보장되지는 않기 때문입니다.