ASP.NET Core 7 버전으로 작성한 Web API를 다른 컴퓨터에서 API 테스트를 하고 싶었다.
로컬 서버를 외부에 공개할 수 있는 방법을 찾다가 ngrok과 Localtunnel을 사용하면 된다는 걸 알게 되었다.
오늘은 Localtunnel에 대한 설명이다.
Localtunnel 란?
웹 서비스로, 로컬 개발 환경에서 작업 중인 웹 사이트나 애플리케이션을 인터넷에 일시적으로 공개하는 것을 가능하게 하는 도구이다.
웹 사이트, 앱 어떻게 작동하는지 데모를 보여주거나,
외부의 사용자들이 데스트를 진행할 수 있도록 허용하는데 유용하다.
Localtunnel을 사용하면, 인터넷에 연결된 어느 누구나 개발 중인 로컬 서버로의 접속을 시도할 수 있다.
동작 원리 :
1. 로컬 서버 실행
2. LocalTunnel 실행하면 LocalTunnel 서버에 연결을 요청한다.
3. LocalTunnel 서버는 고유한 공개 URL을 생성하고 반환해준다.
4. URL을 통해 로컬 서버에 접근할 수 있다.
URL에 대한 모든 트래픽은 LocalTunnel 서버를 통해 사용자의 로컬 서버로 전달된다.
LocalTunnel은 무료로 사용할 수 있으며, 사용자는 자신만의 서브도메인을 선택할 수 있다.
터널이 활성화된 상태에서는 서브도메인은 사용자가 유지하게 되지만,
터널이 닫히면 해당 서브도메인은 다른 사용자에게 할당될 수 있다.
Node.js로 작성된 오픈 소스 프로젝트이며, npm(노드 패키지 매니저)를 통해 설치할 수 있다.
저는 명령어로 설치하는 게 편해서 패키지 매니저 Chocolatey를 활용했다.
Windows 11_Chocolatey 설치
Chocolatey(초콜레티) 란? Windows 운영 체제에서 작동하는 패키지 관리 시스템이다. 소프트웨어를 쉽게 설치하고 업그레이드하고, 관리할 수 있다 Chocolatey는 NuGet 패키지 관리 시스템을 기반으로 하
wallyyoucandoit.tistory.com
설치 전 기본 요구 사항 체크 :
1. Node.js 설치되어 있어야 한다.
2. npm(Node Package Manager) 설치되어 있어야 한다.
* Node.js 환경에서 작동하는 패키지이기 때문이다.
Chocolatey 사용 설치 방법:
1.PowerShell을 열고 다음 명령어를 입력하면 설치 가능 하다.
choco install nodejs
> 위 명령어를 실행하면 Node.js 와 함께 npm 도 설치 된다.
2. npm을 사용하여 LocalTunnel을 설치
npm install -g localtunnel
> 'g' 플래그는 패키지를 전역으로 설치하라는 의미이다. 모드 프로젝트에서 이 패키지를 사용할 수 있게 해 준다.
사용 방법 :
1. 로컬 서버를 실행한다.
2. 로컬 웹 서버 동작하는 포트 번호는 ASP.NET Core 애플리케이션의 'appsettings.json'의 "ServerAddress"의 포트와 일치해야 한다.
3. 아래 명령어를 명령 프롬프트에서 LocalTunnel을 통해 로컬 서버를 인터넷에 공개한다.
lt --port 포트번호
> LocalTunnal은 고유한 URL을 생성하고 반환한다.
생성된 URL은 https://my-subdomain.loca.lt의 형태를 갖게 된다.
>> 서브 도메인 옵션 사용 명령어 예시:
lt --port 포트번호 --subdomain my-subdomain
* URL 간단화하여 테스트 할때 유용 할 수 있다.
4. LocalTunnel 종료 방법은 창을 닫거나 'Ctrl-C'를 누르면 된다.
직접 격은 에러 사항 :
다른 컴퓨터로 URL 접속하면 Localtunnel reminder페이지에
https://ipv4.icanhazip.com 사이트에서 확인한 서버 컴퓨터의 IP를 입력하면
계속 504 Gateway Time-out 에러가 발생했다.
> ngrok는 'Host'헤더를 원래의 로컬 호스트로 다시 작성하게 하는 명령어를 통해 접근 가능했었다.
하지만, LocalTunnel은 HTTP헤더를 재작성하는 기능을 직접 제공하지 않는다고 한다.
내가 찾은 해결 방법은 :
Node.js 서버에서 express.js와 http-proxy-middleware를 활용하여 localtunnel의 헤더를 재작성하는 거다.
// Express.js라이브러리를 import한다.
// Express.js는 웹 애플리케이션을 위한 간결하고 유연한 Node.js 웹 애플리케이션 프레임워크다.
const express = require('express');
// http-proxy-middleware라이브러리에서 createProxyMiddleware 함수를 import 한다.
// 이 함수는 웹 요청을 프록시 서버로 라우팅하는 미들웨어를 만드는데 사용된다.
const { createProxyMiddleware } = require('http-proxy-middleware');
// express 객체를 생성하여 app 변수에 저장
// 이 객체를 사용하여 라우트, 미들웨어, 서버 설정들을 정의 한다.
const app = express();
// Express 미들웨어를 정의한다.
// 모든 요청에 대해 이 함수는 먼저 실행된다.
app.use((req, res, next) => {
// 응답 헤더에 정한 키를 정한다. value 는 어떤 값이든 가능하다
res.setHeader('Bypass-Tunnel-Reminder', 'Your Value');
next(); // 다음 미들웨어로 제어를 전달한다.
});
// 루트 경로('/')에 대한 모든 요청은
// createProxyMiddleware에 의해 생성된 프록시 미들웨어로 라우팅된다.
// "https://localhost:8080" 은 ASP.NET Core appsettings.json에 정한 포트번호와 일치해야한다.
// 프록시는 모든 요청을 "https://localhost:8080"으로 포워딩하며,
// 'changeOrigin' 옵션을 통해 원본 호스트 헤더를 대상 URL로 변경한다.
// 'secure' 옵션은 false로 설명되어 SSL/TLS 검증을 비활성화 하며,
// 자체 서명된 인증서를 사용하는 개발 서버와 같이 신뢰 할 수 없는 인증서에 대한 요청을 허용한다.
app.use('/', createProxyMiddleware({
target: 'https://localhost:8080',
changeOrigin: true,
secure:false
}));
// Exprress 애플리케이션은 3000번 포트에서 시작하도록 설정한다. 실행되면 메시지를 콘솔에 출력
app.listen(3000, () => console.log('Express server running on port 3000'));
> 비주얼 코드로 app.js 에 위에 코드 작성하고 터미널에 node app.js 입력하고 enter 키 누르면 서버가 실행한다.
> localTunnel 실행 명령어도 변경하였다. 포트는 app.js 에 할당한 포트로 url을 요청하였다.
lt --port 3000 --subdomain wally --print-requests
> --print-requests 옵션을 사용하여 request의 결과를 출력하도록 하였다.
LocalTunnel 장점 :
1. 로컬 네트워크 설정이나 방화벽 설정 변경 없이 로컬 서버를 인터넷에 쉽게 공개할 수 있다.
몇 줄 명령어로 접근 허용을 수행할 수 있다.
2. LocalTunnel은 완전히 무료로 사용할 수 있다. 개발자들이 개발 과정에서 비용 걱정 없이 테스트를 진행할 수 있다.
3. 오픈 소스 프로젝트로, 개발자들이 프로젝트에 기여하거나, 필요에 다라 소스 코드를 수정하여 자신이 필요에 맞게 사용할 수 있다.
LocalTunnel 단점 :
1. 로컬 서버가 인터넷에 직접 노출된다. 보안 문제를 일으킬 수 있다.
민감한 정보를 처리하는 애플리케이션의 경우, 반드시 HTTPS 같은 암호화 방법을 사용하여 통신을 보호해야 한다.
2. LocalTunnel 서버가 다운되면, 생성된 터널도 함께 다운된다.
3. 일시적인 테스트나 데모용으로 만들어진 도구이다.
장기적, 안정적인 서비스에는 적합하지 않을 수 있다.
서브도메인이 터널이 닫히는 즉시 다른 사용자에게 할당될 수 있으므로, 장기적인 사용에는 불편함이 있을 수 있다.
*위 내용 오타 및 수정해야 하는 내용 있으면 댓글로 알려주시면 감사합니다.