NGrok URL Getter

a·2022년 5월 30일
0
  • NGrok을 사무실의 Synology NAS에 설치해놓고 외부에서 접속 가능하도록 설정해두었다.
  • URL을 얻으려면 NAS 의 터미널에 접속해서 확인해야 하는데 Docker 재 실행하거나 NAS 재 부팅하면 기존 URL이 변경돼 알 수가 없다.

상기 이유로 인해 결국 URL을 받을 수 있는 프로그램을 개발했다.

현재 사무실의 네트워크 환경은 이렇다

외부 PC에서 회사 건물 공유기로 접속할 수 없는 상태이고, 사무실 내에 공유기는 당연히 접속이 안되니 NAS로 갈 수가 없는 상태이다.
원래는 QuickConnect 같은 걸 사용하겠지만, 시놀로지 서버를 거쳐야되고 내 원하는 포트를 사용하거나 이런게 좀 귀찮아서 NGROK를 선택하기도 했다.

여튼, NAS를 접속할 수 없다면 URL을 알기 전 까지 URL을 알아낼 방법이 없기 때문에 NAS에서 NGROK URL에 대한 정보를 담아서 PC쪽으로 Post request를 대기한다.

그럼 외부(집)에서 PC를 켜고 Post 요청을 수신하는 프로그램을 실행하면 URL을 받도록 개발했다.
코드가 간단해서 쉽게 사용 가능하다.
(사실 파이썬 오랜만에 해서 구현하는덴 오래걸렸음 -_-)

1. NGrok 에서 URL 받아오는 방법

우선 NGROK은 기본 4040포트에서 데이터가 오가는 정보를 확인할 수 있는 모니터링 페이지를 지원한다.
그리고 그 4040포트는 api를 지원하는데

http://{ip or url}:4040/api/tunnels/command_line

해당 URL 에 Get요청을 하면 JSON을 반환하고 해당 JSON에서 "public_url" 를 파싱하면 된다.

2. Code

개발 및 테스트 환경
Client : Windows 11, .net Framework 4.8 (WPF), Visual studio 2022 Community
Server : Synology DSM 7.1, Python3.8 (기본 설치)

// Python

import requests
import os
import json
import time

URL = 'http://{Windows IP}:{port}' # 윈도우 방화벽 인바운드 설정 및 공유기 포트포워딩 필요
param = {'data' : ''}

def getURL():
    try:
        while True:
            try:
                response = requests.get(url='http://localhost:{port}/api/tunnels/command_line') # 포트 default = 4040
                break;
            except(Exception) as e:
                print(e)
                time.sleep(1)

        jsonObject = json.loads(response.content)
        print (jsonObject)
        param['data'] = jsonObject['public_url']
        
        try:
            r = requests.post(URL, data=datas, timeout=5)
        except(Exception) as e:
            time.sleep(1)
    
    except(Exception) as e:
        print (e)

while True:
    getURL()
  • NAS가 켜지면 Docker container 가 켜지는 시간 때문에 제대로 데이터를 파싱하지 못 하는 경우가 생기기 때문에 계속 Exception 캐치, 혹여나 컨테이너 재부팅시에도 적용하기 위해서 캐치가 필요하다.
  • 사실 Docker ps 명령어로 해결 볼 수 있긴 하겠지만 임시로 간단히 쓸 프로그램에 시간을 더 쓰기엔...

// C#

			HttpListener httpListner = new HttpListener();
			httpListner.Prefixes.Add("http://+:{port}/");

			if (!httpListner.IsListening)
			{
				httpListner.Start();
				Task.Factory.StartNew(() =>
				{
					HttpListenerContext context = httpListner.GetContext();
					var request = context.Request;
					var requestData = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding).ReadToEnd();
					JObject json = JObject.Parse(requestData.ToString()); 

					URLBox1.Dispatcher.Invoke(new System.Action(delegate ()
					{
						URLBox.Text = (string)json["data"];
					}), DispatcherPriority.Normal); // url 데이터 띄워 줄 TextBox 필요

					context.Response.Close();
				});
			}
  • 관리자 권한으로 실행해야한다.

상황에 필요한 적당한 모듈은 직접 설치하면 된다.

3. 시놀로지에 적용하는 방법

일단 원하는 폴더내에 py파일을 업로드 해 둔다.

제어판 - 작업 스케줄링 - 트리거된 작업 - 사용자 정의 스크립트

일반 - 사용자 "root", 이벤트 "부트업"
(root로 하지 않으면 모듈 권한인지 모르겠으나 오류가 발생한다.)

작업 설정 - 사용자 정의 스크립트 "python /{py파일 저장한 폴더}" 입력 후 적용

해당 작업을 마치게 되면 재 시작시 자동으로 Post Request를 전송해서 Windows 에서 프로그램을 실행시키면 URL을 받을 수 있다.

얼추 이렇게 보인다.

profile
a

0개의 댓글