1. IP 고정
IP를 고정시키는 가장 큰 이유는, 네트워크 요청이 항상 같은 장치로 정확히 도달하도록 하기 위함이다.
특히 포트 포워딩은 외부에서 들어오는 요청을 특정 내부 IP 주소를 가진 장치로 연결해주는 설정이기 때문에, 해당 장치의 IP가 바뀌면 포트 포워딩 설정이 무효화된다.
이는 대부분의 네트워크에서 사용되는 DHCP(Dynamic Host Configuration Protocol) 때문이다.
DHCP는 장치가 네트워크에 접속할 때 자동으로 IP 주소를 임대(할당)해주는 기능을 한다. 하지만 이 IP 주소는 영구적인 주소가 아니라 일정 시간 동안만 유효한 임시 주소이다.
다음과 같은 상황에서는 IP가 변경될 수 있습니다:
- 장치를 껐다 켜거나 공유기를 재부팅한 경우
- DHCP 임대 시간이 만료되어 새롭게 IP가 재할당된 경우
- 네트워크에 연결된 장치 수나 순서가 달라지면서 IP 충돌을 피하기 위해 공유기가 IP를 다시 배정한 경우
이러한 DHCP의 동작 방식 때문에, 특정 장치에 대해 안정적인 연결이 필요한 경우에는 IP를 고정해두는 작업이 반드시 필요하다.
공유기는 일반적으로 DHCP 기능을 통해 네트워크에 연결된 장치들에게 자동으로 IP를 할당한다. 이때 내가 수동으로 지정한 IP가 DHCP가 사용하는 범위 안에 포함되어 있다면, 공유기는 해당 IP를 다른 장치에도 할당할 수 있어 IP 충돌이 발생할 수 있다.
따라서 고정 IP를 설정할 때는 반드시 DHCP 할당 범위를 피해서, 충돌 위험이 없는 대역을 사용하는 것이 안전하다.
DHCP 할당 범위는 공유기 설정 화면에서 직접 설정할 수 있다.
일반적으로, 기본 게이트웨이는 공유기의 IP 주소이며, 내부 네트워크에서 외부 인터넷으로 나가기 위해서는 반드시 게이트웨이가 필요하다. 대부분의 가정이나 회사에서는 이 역할을 공유기가 담당하기 때문에, 공유기 설정 화면에 접속할 때 사용하는 주소가 곧 기본 게이트웨이 주소가 된다.
DHCP 할당 범위를 일부 축소해 일정 구간을 비워두고, 이 비워진 IP 대역에서 서버나 PC의 IP를 수동으로 지정하면 충돌 없이 안정적으로 내부 IP를 고정할 수 있다.
이더넷 설정에서 DHCP 할당 범위를 피해 IP를 설정하고 게이트웨이에는 공유기의 IP 주소를 입력한다.
2. 포트 포워딩 설정
공유기 설정에서 고정해둔 내부 IP와 열어둘 포트 번호를 입력한다. 간혹 일부 포트가 보안 상의 이유로 통신사에서 차단되어 포트 포워딩이 제한될 수 있다.
3. 방화벽 설정
공유기에서 포트 포워딩을 설정했더라도, 내부 장치의 방화벽이 해당 포트를 차단하고 있다면 외부 요청은 거부된다. 따라서 Windows 방화벽 고급 설정에서 해당 포트를 허용하는 인바운드 규칙을 추가해야 외부 접속이 정상적으로 이루어진다.
4. 포트 리슨
방화벽의 인바운드 규칙까지 설정했으므로 해당 포트에서 실제 서비스가 리슨하고 있다면 외부 요청을 연결할 수 있다. nc(Netcat)를 사용하면 쉽게 테스트 할 수 있지만, Windows Defender에서는 이를 악성 도구로 오인해 자동 삭제하는 경우가 있다. 보안상 Netcat이 해킹 툴로 악용될 수 있기 때문에 생기는 현상이며, 필요한 경우 Defender 예외 설정을 통해 사용이 가능하다.
nc를 실행하여 포트 7777에서 대기한다.
nc -lvnp 7777
listening on [any] 7777 ...
포트 포워딩이 정상적으로 작동하는지 확인하기 위해 YouGetSignal을 이용하여 확인한다. 본인의 공인 IP와 포트 번호를 넣었을 때 open이라고 나온다면 모두 정상적으로 구성된 상태이며 이제 외부 환경에서도 해당 포트로 접근이 가능하다.
https://www.yougetsignal.com/tools/open-ports/
Open Port Check Tool - Test Port Forwarding on Your Router
www.yougetsignal.com
5. WSL2 포트 포워딩(Optional)
Windows에서도 포트를 열 수는 있지만, Netcat처럼 간단하게 포트를 테스트할 수 있는 도구는 기본적으로 내장되어 있지 않다. 반면 WSL에서는 리눅스 기본 도구들을 별도 설치나 우회 없이 바로 사용할 수 있기 때문에, 한 단계 내려가 WSL에서 포트 포워딩 테스트를 진행하는 것이 더 빠르고 효율적일 수 있다.
포워딩 대상인 WSL의 IP 주소를 확인하고 Windows에서 들어온 요청을 WSL 내부 IP로 포워딩하도록 설정한다.
netsh interface portproxy add v4tov4 listenaddress=172.30.1.10 listenport=7777 connectaddress=172.29.47.10 connectport=7777
netsh interface portproxy show all
ipv4 수신 대기: ipv4에 연결:
주소 포트 주소 포트
--------------- ---------- --------------- ----------
172.30.1.10 7777 172.29.47.10 7777
포트 프록시 설정이 완료되면 실제 네트워크 요청은 WSL이 받은 것처럼 동작하며, 내부 리눅스 서버가 직접 응답하게 된다.
하지만, WSL는 가상 머신을 기반으로 동작하기 때문에, WSL을 재시작하거나 Windows를 재부팅할 때마다 IP 주소가 바뀌는 경우가 있다. 이로 인해 위와 같이 netsh interface portproxy 명령으로 수동으로 포트를 포워딩해도, WSL의 IP가 바뀌면 다시 설정해줘야 하는 번거로움이 생긴다.
이러한 문제를 해결하기 위해, 아래와 같은 PowerShell 스크립트를 사용해 WSL의 현재 IP를 자동으로 감지하고, 필요한 포트를 자동으로 포워딩하는 방식을 사용하는 경우도 있다.
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if ( $found ) {
$remoteport = $matches[0];
}
else {
Write-Output "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
$ports = @(7777);
Invoke-Expression "netsh interface portproxy reset";
for ( $i = 0; $i -lt $ports.length; $i++ ) {
$port = $ports[$i];
Invoke-Expression "netsh interface portproxy add v4tov4 listenport=$port connectport=$port connectaddress=$remoteport";
}
Invoke-Expression "netsh interface portproxy show v4tov4";