Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 604. Azure - 윈도우 VM에서 FTP 여는 방법 [링크 복사], [링크+제목 복사]
조회: 1297
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

Azure - 윈도우 VM에서 FTP 여는 방법

당연히, 서버 관리자를 통해 FTP 서비스를 설치했어야 하고, 이후 작업은 포트를 열어야 합니다. 사실상 서비스 설치보다는 포트를 여는 작업이 주가 됩니다. ^^;

전체적인 가이드는 다음의 2개 글에서 잘 설명하고 있습니다.

Installing a secure FTP server on Windows using IIS
; https://winscp.net/eng/docs/guide_windows_ftps_server

Installing secure FTP server on Microsoft Azure using IIS
; https://winscp.net/eng/docs/guide_azure_ftps_server

근래의 환경에서 Active 모드로 FTP 접근을 할 수 있는 곳은 내부망을 제외하고는 없을 것이므로 클라우드에 위치한 Azure VM의 경우 대부분 Passive 모드를 기대하고 설정을 해야 합니다.

따라서, VM과 Azure 측의 VM 네트워크 설정에서 Control과 Data 포트에 해당하는 것을 모두 열어줘야 합니다.

일단 VM 측에서 해야 할 설정을 먼저 볼까요? ^^ 테스트의 편리함을 위해 윈도우 VM의 방화벽은 off 시킨 걸로 하겠습니다. 하지만 FTP 서버에서 FTP Data port로 사용할 범위를 지정해야 하는데요, IIS 관리자에서 다음과 같이 컴퓨터 레벨에서의 "FTP Firewall Support" 설정으로 들어가 "Data Channel Port Range"를 설정하면 됩니다.

azure_vm_ftp_server_1.png

위의 경우, FTP 서버가 Passive 모드를 위한 포트 범위로 49000~49100 사이의 번호를 사용하겠다는 것을 알립니다. 이와 함께, "External IP Address of Firewall" 란에는 해당 VM의 공용 IP를 적어야 합니다. 이 IP 주솟값은 Azure Portal에서 VM 설정의 "Networking" / "Public IP address" 항목을 통해 알 수 있습니다.

자, 그럼 이제 VM 측의 설정은 끝났고, Azure Portal에서의 VM 네트워킹 설정이 남았습니다. 당연히 여기서도 Control/Data 포트를 개방해야 하는데요, "Settings" / "Networking"으로 들어가 "Add Inbound port rule" 버튼을 이용해 다음의 2개 항목을 새롭게 추가합니다.

Destination: Any
Service: FTP 

Service: Custom
Destination port ranges: 49000-49100

끝입니다, 이제 외부에서 Passive 모드로 FTP 연결을 하면 정상적으로 연결이 될 것입니다.




일단, 이론상 저렇게 해서 해결이 되어야 하는데... 경우에 따라 오류가 발생할 수 있습니다.

Status: Connecting to 100.10.5.1:21...
Status: Connection established, waiting for welcome message...
Status: Initializing TLS...
Status: Verifying certificate...
Status: TLS connection established.
Status: Logged in
Status: Retrieving directory listing...
Command:    PWD
Response:   257 "/" is current directory.
Command:    TYPE I
Response:   200 Type set to I.
Command:    PASV
Response:   227 Entering Passive Mode (100,10,5,1,199,125).
Command:    LIST
Response:   150 Opening BINARY mode data connection.
Error:  Connection timed out after 20 seconds of inactivity
Error:  Failed to retrieve directory listing
Status: Disconnected from server

위의 내용을 보면 분명히 Control 포트(21)를 이용한 FTP 서버로의 연결은 정상적으로 되었습니다. 하지만, Passive 모드 정보를 구하는 PASV에 이어 "LIST" 명령을 Control 연결로 보낸 후 응답을 받지 못하고 있는 것입니다. 그리고 그 응답은 "Connection timed out"으로 보아 Data Port로의 연결을 할 수 없었던 것입니다.

아니... 모든 설정이 완벽했는데 왜 passive 모드의 데이터 포트 연결이 안 되었을까요? 원인 분석을 위해 우선 PASV의 응답을 살펴보겠습니다.

Command:    PASV
Response:   227 Entering Passive Mode (100,10,5,1,199,125).

PASV 명령에 대해 FTP 서버는 100,10,5,1,199,125를 내려주고 있는데, 이것의 의미는 앞의 4자리가 IIS FTP에서 설정했던 "External IP Address of Firewall" 값에 해당하는 "100.10.5.1"로 서버의 공용 IP에 해당하고 뒤의 2자리는 포트 번호입니다. 포트 번호의 해석은 다음과 같이 첫 번째 숫자에 대해 256을 곱하고 두 번째 숫자를 더하면 됩니다.

199 * 256 + 125 = 51,069

이상하군요, 우리는 분명 IIS FTP의 "Data Channel Port Range"에 "49000~49100"을 설정해 두었는데 그것을 무시하고 서버는 51069 포트 번호를 내려주고 있는 것입니다. 당연히 이 번호는 Azure VM의 네트워크 설정에서 열어주지 않은 포트라서 클라이언트가 접속할 수 없습니다.

이후, 몇 번의 FTP 연결 로그에서도 5만 번대의 포트 번호가 내려왔고 테스트를 위해 Azure 네트워크 설정의 "Add Inbound port rule"에서 "50000-60000"으로 지정해 열었더니 FTP 연결이 정상적으로 되었습니다. ^^;

아마도 FTP 서버는 dynamic port 범위 내에서,

PS C:\windows\system32>  netsh int ipv4 show dynamicport tcp

Protocol tcp Dynamic Port Range
---------------------------------
Start Port      : 49152
Number of Ports : 16384

데이터 포트를 결정해 내려주는 것 같았습니다. 오호... 그렇다면 혹시 FTP 서버가 "Data Channel Port Range" 설정을 아직 반영하지 못한 것이 아닐까요? 그래서 아예 VM을 재부팅하고 다시 테스트했더니,

Command:    PASV
Response:   227 Entering Passive Mode (100,10,5,1,191,104)

191 * 256 + 104 = 49,000이니까, 정상적으로 49000부터 시작하는 포트를 내려주었습니다. ^^;




만약 FTP 클라이언트 측에서 다음과 같은 오류가 발생한다면?

C:\temp> ftp
ftp> open localhost
> ftp: connect :Connection refused

아마도 VM에 FTP 서비스만 설치하고 IIS 관리자에서 "Add FTP Site..."를 이용해 실제 FTP 사이트를 등록하지 않은 상태일 것입니다. FTP 사이트를 설치하면 다음과 같은 식으로 진행하는 것을 확인할 수 있습니다.

ftp> open localhost
Connected to testvm.
220 Microsoft FTP Service
200 OPTS UTF8 command successful - UTF8 encoding now ON.
User (testvm:(none)):




만약 user 로그인 시 다음과 같은 오류가 발생한다면?

User (testvm:(none)): testusr
534 Policy requires SSL.
Login failed.

윈도우의 기본 ftp.exe 클라이언트는 FTP over SSL을 지원하지 않으므로 저런 경우 접속할 수 없습니다. 만약 서버 관리자이면서 보안이 중요하지 않다면 IIS의 "FTP SSL Settings"를 통해 "Require SSL connections"로 지정된 기본값을 "Allow SSL connection"으로 낮출 수는 있습니다.

혹은, 기본 ftp.exe 이외에 FTP over SSL을 지원하는 FileZilla같은 별도의 FTP 클라이언트를 이용하면 됩니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 11/14/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  [10]  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
12894정성태12/30/20211289.NET Framework: 1125. C# - DefaultObjectPool<T>의 IDisposable 개체에 대한 풀링 문제 [3]파일 다운로드1
12893정성태12/27/20211538.NET Framework: 1124. C# - .NET Platform Extension의 ObjectPool<T> 사용법 소개파일 다운로드1
12892정성태12/26/20211110기타: 83. unsigned 형의 이전 값이 최댓값을 넘어 0을 지난 경우, 값의 차이를 계산하는 방법
12891정성태12/23/20211000스크립트: 38. 파이썬 - uwsgi의 --master 옵션
12890정성태12/23/20211089VC++: 152. Golang - (문자가 아닌) 바이트 위치를 반환하는 strings.IndexRune 함수
12889정성태12/22/20211604.NET Framework: 1123. C# - (SharpDX + DXGI) 화면 캡처한 이미지를 빠르게 JPG로 변환하는 방법파일 다운로드1
12888정성태12/21/20211373.NET Framework: 1122. C# - ImageCodecInfo 사용 시 System.Drawing.Image와 System.Drawing.Bitmap에 따른 Save 성능 차이파일 다운로드1
12887정성태12/21/20211509오류 유형: 777. OpenCVSharp4를 사용한 프로그램 실행 시 "The type initializer for 'OpenCvSharp.Internal.NativeMethods' threw an exception." 예외 발생
12886정성태12/20/20211185스크립트: 37. 파이썬 - uwsgi의 --enable-threads 옵션
12885정성태12/20/2021959오류 유형: 776. uwsgi-plugin-python3 환경에서 MySQLdb 사용 환경
12884정성태12/20/2021974개발 환경 구성: 620. Windows 10+에서 WMI root/Microsoft/Windows/WindowsUpdate 네임스페이스 제거
12883정성태12/19/20211273오류 유형: 775. uwsgi-plugin-python3 환경에서 "ModuleNotFoundError: No module named 'django'" 오류 발생
12882정성태12/18/20211012개발 환경 구성: 619. Windows Server에서 WSL을 위한 리눅스 배포본을 설치하는 방법
12881정성태12/17/20211249개발 환경 구성: 618. WSL Ubuntu 20.04에서 파이썬을 위한 uwsgi 설치 방법 (2)
12880정성태12/16/20211031VS.NET IDE: 170. Visual Studio에서 .NET Core/5+ 역어셈블 소스코드 확인하는 방법
12879정성태12/16/20214366오류 유형: 774. Windows Server 2022 + docker desktop 설치 시 WSL 2로 선택한 경우 "Failed to deploy distro docker-desktop to ..." 오류 발생
12878정성태12/15/20211203개발 환경 구성: 617. 윈도우 WSL 환경에서 같은 종류의 리눅스를 다중으로 설치하는 방법
12877정성태12/15/20211002스크립트: 36. 파이썬 - pymysql 기본 예제 코드
12876정성태12/14/20211040개발 환경 구성: 616. Custom Sources를 이용한 Azure Monitor Metric 만들기
12875정성태12/13/20211057스크립트: 35. python - time.sleep(...) 호출 시 hang이 걸리는 듯한 문제
12874정성태12/13/2021869오류 유형: 773. shell script 실행 시 "$'\r': command not found" 오류
12873정성태12/12/20211301오류 유형: 772. 리눅스 - PATH에 등록했는데도 "command not found"가 나온다면?
12872정성태12/12/20211090개발 환경 구성: 615. GoLang과 Python 빌드가 모두 가능한 docker 이미지 만들기
12871정성태12/12/20212025오류 유형: 771. docker: Error response from daemon: OCI runtime create failed
12870정성태12/9/2021992개발 환경 구성: 614. 파이썬 - PyPI 패키지 만들기 (4) package_data 옵션
12869정성태12/8/20211203개발 환경 구성: 613. git clone 실행 시 fingerprint 묻는 단계를 생략하는 방법
1  2  3  4  5  6  7  8  9  [10]  11  12  13  14  15  ...