ipTIME 공유기로 두 지역·세 지역 사무실을 하나의 네트워크로 연결하기 (WireGuard, 2026 업데이트)

2023년에 공유기 2대로 두 사무실을 연결한 글을 올렸는데, 지금은 3대로 늘려서 세 지역을 하나의 네트워크처럼 쓰고 있습니다. 실제 운영 중인 구성 기준으로 전면 개정했습니다.

사무실이나 집이 여러 곳으로 나뉘면 “저쪽 NAS에 있는 파일 좀 열어줘”, “저쪽 프린터로 출력하고 싶은데” 같은 요청이 매일 생깁니다. 여러 지역을 하나의 네트워크로 묶는 방법은 전용회선, 전용 VPN 라우터, 클라우드 VPN 등 여러 가지가 있지만, 여기서는 가장 저렴한 방법인 ipTIME 공유기끼리 WireGuard VPN으로 직접 연결하는 방식을 정리합니다. 추가 장비나 월 비용 없이 공유기만으로 구성됩니다.

연결 방법 비교

방식비용난이도비고
통신사 전용회선월 수십만 원 이상낮음(업체 시공)가장 안정적이지만 소규모에는 과함
전용 VPN 라우터 (MikroTik, UniFi 등)장비비 수십만 원높음기능은 풍부하지만 설정이 복잡
Tailscale / ZeroTier 서브넷 라우터무료~유료중간공인 IP 불필요. 상시 켜진 기기 필요
ipTIME 공유기 VPN공유기 값만낮음이 글의 방법

전체 구성

ipTIME 공유기 3대 WireGuard 허브 앤 스포크 구성도
역할내부 대역모델WireGuard 서버 터널 주소
지점 A192.168.45.0/24A3004TW10.0.37.1
허브192.168.10.0/24A3008-MU10.0.195.1
지점 B192.168.0.0/24A5004NS-M10.0.180.1
  • 세 대 모두 펌웨어 15.36.6
  • 허브를 중심으로 지점 A, 지점 B가 연결되는 허브 앤 스포크 구조
  • 공유기마다 WireGuard 서버와 클라이언트를 동시에 사용
  • 허브와 각 지점 사이에 방향별로 터널 1개씩, 총 4개
허브 공유기 시스템 정보 (A3008-MU, 192.168.10.1)
지점 A 공유기 시스템 정보 (A3004TW, 192.168.45.1)
지점 B 공유기 시스템 정보 (A5004NS-M, 192.168.0.1)

허브 앤 스포크 구조란

허브 앤 스포크(Hub and Spoke)는 자전거 바퀴에서 온 이름입니다. 가운데 축(허브)이 있고, 바큇살(스포크)이 축에서 바깥으로 뻗어 나가는 모양입니다. 네트워크에서는 모든 지점이 중앙의 허브 한 곳에만 연결되고, 지점끼리는 허브를 거쳐 통신하는 구조를 말합니다.

항공 노선을 떠올리면 쉽습니다. 지방 공항끼리 모두 직항을 만드는 대신, 인천 같은 허브 공항 한 곳에 노선을 모으고 환승으로 연결하는 방식입니다. 반대로 모든 지점을 서로 직접 연결하는 구조는 풀메시(Full Mesh)라고 부릅니다.

허브 앤 스포크와 풀메시 연결 구조 비교
항목허브 앤 스포크풀메시
연결 수 (지점 n곳)n−1n(n−1)/2
지점 추가 시 작업허브와 새 지점만 연결기존 모든 지점과 연결
지점 간 경로허브 경유직접
지점 간 속도허브 회선·공유기에 좌우두 지점 회선에만 좌우
허브 장애 시전체 지점 간 통신 중단해당 지점만 영향
관리허브 한 곳 중심으로 단순지점이 늘수록 급격히 복잡

이 글의 구성에서는 192.168.10.0/24 공유기가 허브, 192.168.45.0/24와 192.168.0.0/24 공유기가 스포크입니다. ipTIME에서는 허브와 지점 사이에 방향별로 터널을 하나씩 두기 때문에, 실제 터널 수는 연결 수의 두 배입니다. 지점 3곳이면 허브 앤 스포크는 터널 4개, 풀메시는 6개가 필요합니다.

허브를 고르는 기준

  • 인터넷 회선이 가장 빠르고 안정적인 곳
  • 공인 IP 또는 DDNS 접속이 안정적인 곳
  • 공유기가 항상 켜져 있는 곳
  • 가능하면 CPU 성능이 가장 좋은 공유기

풀메시가 나은 경우

  • 지점끼리 대용량 파일 전송이 잦은 경우
  • 허브 장애로 전체가 끊기는 상황을 허용할 수 없는 경우

두 방식을 섞을 수도 있습니다. 기본은 허브 앤 스포크로 두고, 트래픽이 많은 두 지점 사이에만 직접 터널을 추가하는 방식입니다.

왜 터널을 방향별로 하나씩 만드나

처음 2대로 연결했을 때 가장 헷갈린 부분입니다. 한쪽을 서버, 다른 쪽을 클라이언트로 연결하면 클라이언트 쪽에서는 상대 네트워크가 보이는데, 서버 쪽에서는 클라이언트 뒤의 네트워크로 들어가지 못하는 상황이 생깁니다.

상대 대역으로 가는 경로는 WireGuard 클라이언트를 가진 쪽에서 “클라이언트 사용 관리”로 지정합니다. 서버 쪽에는 클라이언트 뒤의 네트워크로 가는 경로를 지정할 곳이 없습니다. 그래서 규칙은 단순합니다. “내가 가고 싶은 쪽의 서버에 내가 클라이언트로 붙는다.”

  • 지점 → 허브: 지점 공유기가 허브 서버에 클라이언트로 접속 (터널 10.0.195.x)
  • 허브 → 지점: 허브 공유기가 각 지점 서버에 클라이언트로 접속 (터널 10.0.37.x, 10.0.180.x)

1단계. IP 대역 분리

ipTIME은 기본값이 모두 192.168.0.1이기 때문에, 그대로 두면 네트워크가 충돌해서 라우팅이 불가능합니다. 공유기마다 서로 다른 대역을 써야 합니다. 이 구성에서는 45, 10, 0 세 대역을 사용합니다.

대역을 바꾸면 기존에 고정 IP로 설정한 프린터나 NAS 주소도 함께 바뀌므로, 사용자가 적은 시간에 작업하는 것이 좋습니다.

2단계. 각 공유기에 WireGuard 서버 켜기

세 대 모두 VPN 설정 → WireGuard 서버 설정에서 서버를 활성화합니다.

  • DDNS 등록 (ipTIME DDNS). 공인 IP가 바뀌어도 접속 주소 유지
  • 포트는 기본값 51820 대신 공유기마다 다른 포트 사용
  • 통신사 모뎀 뒤에 공유기가 있는 이중 NAT 환경이면 모뎀에서 해당 UDP 포트 포워딩 필요
  • 피어 추가 직후 나오는 설정 화면은 닫으면 다시 볼 수 없으므로 설정 파일을 먼저 내려받기

허브 서버에는 지점 공유기 2대가 피어로 등록됩니다. 같은 서버에 노트북, 폰, 태블릿, 클라우드 서버도 함께 등록해서 쓰고 있습니다. 서버 하나로 사이트 간 연결과 개인 기기 원격 접속을 동시에 처리하는 구조입니다.

허브 WireGuard 서버의 피어 목록 — 지점 공유기 2대와 개인 기기

3단계. WireGuard 클라이언트 연결

지점 쪽: 각 지점 공유기의 WireGuard 클라이언트에 허브 서버를 등록합니다.

지점 B의 WireGuard 클라이언트 — 허브 서버에 연결
지점 A의 WireGuard 클라이언트 — 허브 서버에 연결

허브 쪽: 허브 공유기의 WireGuard 클라이언트에 지점 A, 지점 B 서버를 각각 등록합니다.

허브의 WireGuard 클라이언트 — 지점 A, 지점 B 서버에 각각 연결

4단계. 클라이언트 사용 관리에서 목적지 라우팅

터널만 연결해서는 상대 대역으로 트래픽이 가지 않습니다. VPN 설정 → 클라이언트 사용 관리에서 “이 목적지로 가는 트래픽은 이 터널로” 규칙을 추가합니다.

  • 단말: 전체 (내부 모든 기기에 적용)
  • 목적지: 상대 대역 (예: 192.168.10.0/24)
  • VPN: 해당 WireGuard 클라이언트

지점 A의 설정입니다. 허브 대역뿐 아니라 지점 B 대역까지 허브 터널로 보내도록 두 개의 규칙을 넣었습니다.

지점 A의 클라이언트 사용 관리 — 허브 대역과 지점 B 대역 모두 허브 터널로
목적지사용 터널
192.168.10.0/24 (허브)허브로 가는 클라이언트
192.168.0.0/24 (지점 B)허브로 가는 클라이언트

다른 공유기에서 다른 지점으로 가야 할 때도 같은 원리로, 가려는 대역을 해당 방향의 클라이언트 터널로 보내는 규칙을 추가하면 됩니다.

목적지를 지정하는 방식이라 지정한 대역만 VPN을 타고, 일반 인터넷 트래픽은 각 지점 회선으로 그대로 나갑니다. 모든 트래픽을 허브로 보내는 것이 아니기 때문에 지점 인터넷 속도에는 영향이 없습니다.

5단계. 연결 확인

2대 구성과 달리 3대 구성에서는 지점 A에서 지점 B로 가는 경로가 핵심입니다. 두 지점 사이에는 직접 터널이 없지만, 4단계에서 지점 B 대역을 허브 터널로 보내도록 했기 때문에 허브를 거쳐 접속됩니다. traceroute로 경로를 확인해봤습니다.

지점 A에서 지점 B(192.168.0.68)로 traceroute
홉주소의미
110.0.37.1지점 A 공유기
210.0.195.1허브 공유기
310.0.180.1지점 B 공유기
4192.168.0.68목적지 기기

지점 A → 허브 → 지점 B 순서로 허브가 두 터널 사이를 중계하고 있습니다. 지점 A는 라우팅 규칙에 따라 지점 B행 패킷을 허브 터널로 보내고, 허브는 자신의 라우팅 규칙에 따라 지점 B로 가는 클라이언트 터널로 넘깁니다.

덕분에 지점끼리 직접 터널을 만들지 않아도 됩니다. 지점이 늘어나도 터널은 허브와 새 지점 사이에 2개만 추가하고, 나머지는 기존 지점에 새 대역의 라우팅 규칙 한 줄씩 넣으면 됩니다. 모든 지점끼리 직접 연결하는 풀메시였다면 3대에서 터널 6개, 4대에서 12개가 필요했을 것입니다.

허브 경유의 단점

  • 지점끼리 트래픽이 허브 회선의 다운로드와 업로드를 모두 사용
  • 허브 공유기가 암복호화를 두 번 수행하므로 지점 간 속도는 허브 연결보다 낮음
  • 허브 공유기나 허브 회선이 멈추면 지점끼리도 끊김

지점끼리 대용량 전송이 잦다면 해당 지점 사이에만 직접 터널을 추가하는 방식으로 보완할 수 있습니다.

속도: L2TP vs WireGuard

2023년 2대 구성 당시, 같은 회선과 같은 공유기에서 프로토콜만 바꿔 측정한 결과입니다.

프로토콜다운로드업로드
L2TP16.3 Mbps26.7 Mbps
WireGuard102 Mbps132 Mbps

측정은 허브 LAN에 설치한 OpenSpeedTest 서버(192.168.10.100)에 다른 지점에서 VPN으로 접속해서 진행했습니다.

L2TP VPN 경유 속도 측정 — 다운로드 16.3Mbps, 업로드 26.7Mbps
WireGuard VPN 경유 속도 측정 — 다운로드 102.0Mbps, 업로드 132.3Mbps

Ping 차이는 1ms 정도로 거의 같지만, 처리량은 약 5~6배 차이가 납니다. L2TP/IPsec은 암호화 처리가 무거워서 공유기 CPU가 먼저 한계에 걸리기 때문입니다. 공유기끼리 연결하는 용도라면 WireGuard를 쓰지 않을 이유가 거의 없습니다. L2TP는 별도 앱 없이 윈도우·맥·스마트폰 기본 기능으로 접속해야 하는 경우에 대안으로 쓰는 것이 맞습니다.

VPN 속도의 상한은 양쪽 회선 중 느린 쪽의 업로드 속도와 공유기 CPU 성능입니다.

자주 막히는 문제

VPN은 연결됐는데 상대 PC에 ping이 안 감

  • 원인 대부분이 윈도우 방화벽. 윈도우는 기본적으로 ping(ICMP)과 파일 공유를 “로컬 서브넷”에서만 허용
  • 해결: 방화벽 인바운드 규칙의 원격 IP 범위에 상대 대역 추가

한쪽에서만 접속되고 반대쪽에서는 안 됨

  • 목적지 라우팅은 클라이언트를 가진 쪽에서만 지정 가능
  • 해결: 반대 방향으로도 클라이언트 터널 추가 (이 글의 방향별 터널 구조)

네트워크 탭에 상대 지역 PC가 안 보임

  • 네트워크 검색은 브로드캐스트 기반이라 다른 대역으로 넘어가지 않는 것이 정상
  • 해결: \\IP주소로 직접 접속하거나 네트워크 드라이브로 연결

허브는 되는데 다른 지점으로는 안 됨

  • 지점의 클라이언트 사용 관리에 다른 지점 대역 규칙이 빠진 경우
  • 해결: 다른 지점 대역도 허브 터널로 보내는 규칙 추가

클라이언트가 서버에 아예 접속을 못 함

  • 이중 NAT 여부와 포트포워딩 확인
  • DDNS 주소가 현재 공인 IP를 가리키는지 확인
  • 공인 IP가 아닌 사설 IP를 할당받는 회선(CGNAT)이면 서버 역할을 다른 쪽으로 옮기거나 Tailscale 같은 방식 검토

속도가 기대보다 낮음

  • 저가형 모델은 CPU가 병목. 양쪽 업로드 속도도 확인

보안 팁

  • 외부에 여는 포트는 WireGuard 포트만
  • 기본 포트 대신 공유기마다 다른 포트 사용
  • 피어 설정 파일에는 개인키가 들어 있으므로 메신저 등에 남기지 않기
  • 사용하지 않는 피어는 삭제
  • 공유기 관리자 페이지 원격 관리 기능은 끄기
  • 펌웨어 최신 버전 유지

마무리

ipTIME 공유기만으로도 여러 지역을 하나의 네트워크처럼 묶을 수 있습니다. 핵심은 세 가지입니다. 대역을 겹치지 않게 나누고, 가고 싶은 방향으로 클라이언트 터널을 만들어 목적지 라우팅을 걸고, 지점이 여러 개면 허브를 두어 중계하게 하는 것입니다. 지점이 늘어나도 터널 2개와 라우팅 규칙 몇 줄만 추가하면 되기 때문에, 확장도 어렵지 않습니다.

wordpress에서 라이브러리와 블로그 링크

wordpress로 블로그를 올리고 미디어 파일을 올립니다. 그런데 미디어파일을 별도로 올리거나 하는 경우 아래와 같이 미디어 파일과 블로그의 글의 링크가 깨지는 경우가 있습니다.

아래의 스크립트를 돌리면 이러한 글들을 미디어파일과 블로그 글을 링크로 연결 해줍니다.

# -*- encoding:utf8 -*-
from curses.ascii import isdigit
from select import select
from turtle import Screen, isvisible
import requests
import random
from configparser import ConfigParser
from selenium import webdriver
from bs4 import BeautifulSoup
import sys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import math
from selenium.webdriver.support.ui import Select
import logging
import os
from Screenshot import Screenshot_Clipping
from PIL import Image
from inspect import currentframe, getframeinfo
from urllib.request import Request, urlopen
from datetime import datetime,date,timedelta
from requests.auth import HTTPBasicAuth
import json
import base64, json, re, requests

In [ ]:

username = 'ID'
password = 'PW'
baseurl = "https://flywithu.com/wp-json/wp/v2"

In [ ]:

credentials = username + ':' + password
token = base64.b64encode(credentials.encode())

header = {
'Authorization': 'Basic ' + token.decode('utf-8'),
'Content-Type': 'application/json'}

In [ ]:

page = 1
per_page=30
mymedias=[]
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/media", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1
    if(item_count<per_page):
        break
    # print(result)
    mymedias.extend(result)
    print("*",end="")

In [ ]:

page = 1
per_page=30
myposts=[]
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/posts", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1

    # print(result)
    myposts.extend(result)
    print("*",end="")
    if(item_count<per_page):
        break
page=1
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/pages", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1

    # print(result)
    myposts.extend(result)
    print("*",end="")
    if(item_count<per_page):
        break

In [ ]:

def download_file(url, save_path):
    response = requests.get(url)
    
    if response.status_code == 200:
        with open(save_path, 'wb') as file:
            file.write(response.content)
        print(f"파일 다운로드 완료: {save_path}")
    else:
        print("파일 다운로드 실패")

In [ ]:

def attach_media_to_post(post_id, attachment_id, baseurl, authname,authpass):
    # 첨부 요청

    credentials = authname + ':' + authpass
    token = base64.b64encode(credentials.encode())

    header = {
   'Authorization': 'Basic ' + token.decode('utf-8'),
   'Content-Type': 'application/json'
}



    
    targetpost = f'{baseurl}/media/{attachment_id}'
    data = {'post':post_id}
    response = requests.post(targetpost, headers=header, data=json.dumps(data))



    if response.status_code == 200:
        # 첨부 성공
        print('미디어 파일이 블로그 글에 첨부되었습니다.')
    else:
        # 첨부 실패
        print('미디어 파일 첨부에 실패했습니다.')
        print(response.text)

In [ ]:

from urllib.parse import urlparse

count = 0 
for mymedia in mymedias:
    # myone = os.path.basename()
    myone =  urlparse(mymedia['guid']['rendered']).path
    print(myone)
    for post in myposts:
        content = post['content']['rendered']
        if myone in content:
            print(post['id'],mymedia['id'])
            attach_media_to_post(post['id'],mymedia['id'],baseurl,username,password)

wordpress에서 미사용 미디어 라이브러리 삭제

최근 몇일동안 사이트 사용에 문제가 있었습니다. 예를들어 댓글이 작성이 안되는 문제였습니다. 그 이유는 웹호스팅 디스크 Full 때문이었습니다.

그동안 중복해서 올린 media 라이브러리가 많았는데, 사용하지 않는 미디어파일을 삭제 하는 노트북 파일 입니다.

파일명으로만 검색하기 때문에, 동일한 파일명으로 사용중일때는 있는 것으로 판단합니다. 즉 좀 더 보수적으로 판단 됩니다. 정확하게는 경로명까지 봐서 판단해야 하는데, 이거는 다음에 올린 다음 버젼에서 적용 되었습니다.

ID/PW 부분만 변경해서 사용하면 동작 할것 입니다.

# -*- encoding:utf8 -*-
from curses.ascii import isdigit
from select import select
from turtle import Screen, isvisible
import requests
import random
from configparser import ConfigParser
from selenium import webdriver
from bs4 import BeautifulSoup
import sys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import math
from selenium.webdriver.support.ui import Select
import logging
import os
from Screenshot import Screenshot_Clipping
from PIL import Image
from inspect import currentframe, getframeinfo
from urllib.request import Request, urlopen
from datetime import datetime,date,timedelta
from requests.auth import HTTPBasicAuth
import json
import base64, json, re, requests

In [244]:

username = 'ID'
password = 'Password'
baseurl = "https://flywithu.com/wp-json/wp/v2"


In [245]:

credentials = username + ':' + password
token = base64.b64encode(credentials.encode())

header = {
'Authorization': 'Basic ' + token.decode('utf-8'),
'Content-Type': 'application/json'}

In [246]:

page = 1
per_page=30
mymedias=[]
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/media", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1
    if(item_count<per_page):
        break
    # print(result)
    mymedias.extend(result)
    print("*",end="")
**********************

In [247]:

page = 1
per_page=30
myposts=[]
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/posts", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1

    # print(result)
    myposts.extend(result)
    print("*",end="")
    if(item_count<per_page):
        break
page=1
while True:
    data = {
    'per_page': per_page,
    'page': page
    }

    response = requests.get(baseurl+"/pages", headers=header,data=json.dumps(data))
    result = response.json()
    item_count = len(result)
    page=page+1

    # print(result)
    myposts.extend(result)
    print("*",end="")
    if(item_count<per_page):
        break
****************************************************************

In [248]:

mycontent=""
for post in myposts:
    content = post['content']['rendered']
    mycontent=mycontent+content
    
    

In [249]:

def save_text_to_file(text, file_path):
    with open(file_path, 'w') as file:
        file.write(text)

save_text_to_file(mycontent,"result.txt")

In [250]:

def download_file(url, save_path):
    response = requests.get(url)
    
    if response.status_code == 200:
        with open(save_path, 'wb') as file:
            file.write(response.content)
        print(f"파일 다운로드 완료: {save_path}")
    else:
        print("파일 다운로드 실패")

In [251]:

if 'Myimage-29.png' in mycontent:
    print("OK")

In [252]:

mymedia_hash=[]
count = 0 
for mymedia in mymedias:
    myone = os.path.basename(mymedia['guid']['rendered'])
    if myone not in mycontent:
        print(myone)
        print(mymedia['guid']['rendered'])
        print(mymedia['id'])
        download_file(mymedia['guid']['rendered'],"data/"+myone)
        deleteurl = baseurl+f"/media/{mymedia['id']}"
        print(deleteurl)
        count=count+1

        data = {
    'id': mymedia['id'],
    'force': 1,
    }
        print(data)
        res = requests.delete(deleteurl,headers=header,data=json.dumps(data))
        print(res.status_code)

print(count)
tmpr5ze2f_a.png
https://flywithu.com/wp-content/uploads/2023/05/tmpr5ze2f_a.png
6831
파일 다운로드 완료: data/tmpr5ze2f_a.png

GPT to WordPress 파이썬 코드

https://flywithu.com/gpt-%ec%82%ac%ec%9a%a9-%ed%9b%84%ea%b8%b0/

이글에서 언급된 파이썬 코드 입니다.

개발 환경은 Kaggle 서버 입니다. (www.kaggle.com)
여기의 장점은 스케줄링이 되서, 매일 한번씩 코드가 자동 실행 됩니다. 그것도 무료로!
스케줄링 설정은 아래와 작성한 파이썬에 대해서 설정해줍니다. 그러면 UTC 0 (9:00AM KST)에 실행이 됩니다.

사실 코드가 별로 길지도 않아서..
먼저 OpenAI의 API Key를 가져 옵니다. (https://platform.openai.com/account/api-keys)

그리고 wordpress의 Key도 가져 옵니다.

https://github.com/metaqsol/card/blob/main/gpt-to-wordpress.ipynb

코드는 위와 같습니다.

GPT 사용 후기

아무말 대잔치로 GPT를 통해서 Post를 해보았습니다. 몇번의 시행착오를 겪었는데,
처음에는 네이버 기사를 가져와서 글을 쓰게 했는데.. 정말 정말 아무말 대잔치.
GPT는 2021년까지 밖에 모르니, 최신 뉴스를 가져와서 글을 쓰게 하니.

그래서 그 다음으로 한거는 이미 알고 있고, 그리고 재미도 있을만한 옛날 이야기를 작성하게 했습니다.

https://flywithu.com/category/chatgpt/

아래와 같이 글을 작성해주는데, GPT도 알고 있던 시대이니, 본문도 맞지 않을까 싶습니다.
그러나 내용의 깊이는 부족하지 않나 싶습니다. 뭔가 프롬프트를 개선해야 할 것 같습니다.

아무말 대잔치의 결과를 보자면.. 포스팅 한개에 0.04$정도 비용이 발생하고, 트래픽으로 보면 아래과 같이 소폭 상승은 했습니다.

그러나 이렇게 생성된 Contents가 개인적으로 별로 유용하지 않습니다. 내가 저 내용을 알아서 뭐할꺼며.. 아마 Wiki를 보는게 더 정확하고 내용이 깊을것 같습니다. 그러나 내용을 표현해주는 Dali의 그림을 좋아 보입니다. 추후에도 Dali는 좀 사용하것 같습니다.

개인적으로 ChatGPT를 최근에 활용했던 것은
글 작성 -> GPT를 통해서 내용을 좀 더 풍부하게, 그리고 맞춤법등의 보정 -> 글 수정 및 퇴고
의 과정에서 사용했습니다. 그러나 내용을 풍부하게 하면서, 가짜 근거를 만들고 붙여줘서, 마지막 단계에서는 정말 잘 읽어봐야 했습니다.

종합적으로 보면, 내가 정답을 검증 할수 있거나(Code), 정답이 없는 것 (그림 같은거)는 확실히 GPT/DALI가 좋습니다. 그러나 내가 모르는 것에 GPT를 이용했다가는 낭패를 겪을수 있습니다.

하도 GPT를 이용한 자동 포스팅이 유행이라, 공짜 credit으로 한번 해보았으나, 향후에는 보정용으로만 활용하지, 완전히 작성용으로는 사용 안 할것 같습니다. 여기에 사용한 코드 및 간단한 메뉴얼은 별도 포스팅으로 남깁니다.

ChatGPT 활용해보기…

ChatGPT API사용하는게.. 오늘 보니. 활성화가 되어 있었다.
이거 가입시 한번만 주는건데. 내가 언젠가 그냥 활성화를 했나 보다.

이거 돈이 아까워서 그냥 활용해보기로 했다.

CHATGPT – flywithu

처음에는 그림이 생뚱맞은게 그려 졌는데. 이제는 어느정도 본문과 관련 있는 것이 나오고 있다. 이래서 프롬프트 엔지니어가 있는건가…

어쨌던 어서 18$ 다 써버려야지. 다 쓴 다음에도 그냥 자동으로 좀 올리게 할 예정이다..

Tmap Malware(해킹앱) 관련

안녕하세요. 1주일전 소식인데, 이제야 확인을 했습니다.

  1. github 에 올라가 있는 tmap apk는 삭제 했습니다.
  2. 이유는 현재 tmap이 Malware(악성앱) 입니다. 아래 두개 기사를 확인 해보시면 됩니다.
  3. 엘포인트, 롯데시네마, 곰 등 감염시킨 골도슨 멀웨어, 1억 회 다운로드 돼 (boannews.com)
  4. Goldoson: Privacy-invasive and Clicker Android Adware found in popular apps in South Korea | McAfee Blog
  5. 작업했던 9.15 버젼도 악성 앱이 감염되어 있음을 확인 했습니다.
  6. tmap/nepkt_hrnRzCx.smali at v9.15.0 · flywithu/tmap (github.com)

이번 악성앱건은 오염된 라이브러리를 사용한 것이 아니라, 내부 또는 외주 개발자가 고의적으로 감염시킨것으로 생각 됩니다.
McAfee에서 발표한 문제 도메인리스트 입니다.

그리고 Tmap의 코드를 보면 아래 파일에 해당 도메인이 있습니다. 이 클래스의 네임스페이스는 SKlib 입니다. 즉 내부 라이브러리임을 알 수 있습니다.

그러면 과연 언제 부터 이 라이브러리가 사용 되었을까요? bhuroid 의 도메인을 확인해보면.. 2020년 생성했고, 한국에서 만들어진 도메인입니다.
그래서 한국의 앱들이 이 Malware를 가지게 된 이유를 상상해볼수 있습니다.

TMAP 8 에서도 해당 코드가 있는 것을 확인 하였고, 꽤 오래전 부터, 수년간 Tmap에 악성코드를 탑재해서 제공 되었을것으로 예상됩니다.

위 McAfee를 들어가 보면 많은 한국앱들이 감염되어 있습니다. 개인적인 생각으로는 엄청난 개발자 또는 그룹이 있고, 그들이 한국의 앱들은 다 만드나 보네요. 그러면서 .. 이런거를 심은거가 아닐까 싶습니다. 이렇게 광고 클릭했으면.. 엄청 부자가 되었을듯….;;;;;;

그런데 TMobile 코드를 정적 분석 같은거 안하나 !!
그런거에서 이상한 String 충분히 검색할 수 있지 않나.
그리고 몇년동안 이랬으면 최소한 자세한 내용을 알려 줘야 하지 않나.
그냥 ‘버그 수정’ 을 수정사항이라고 하고 업데이트 하다니.

시간이 남을때 최신 Tmap에 기존 수정 사항들 적용해서 배포 하겠습니다. ㅠㅠ

아래는 문제 앱 리스트 입니다. 상단의 McAfee에서 모든 목록을 받을수 있습니다.
(GP: Status가 Updated는 Playstore 에서 업데이트가 되었다는 것이고,
Removed는 Playstore 에서 삭제 되었다는 것입니다. )

VPN (Surfahsrk)

아래 주소로 신청하면 프로모션이 적용 됩니다.
https://get.surfshark.net/aff_c?offer_id=926&aff_id=19190


월 2.3$ + 2개월 무료

기존에 Ivacy VPN을 사용했는데, 이번에 Surfshark로 이전 했습니다. Ivacy는 5년 계약시 월 1$로 매우 저렴합니다. 그러나 속도 및 국가 커버리지에서 Surfshark가 더 좋습니다.

지원하는 서버는 아래와 같습니다

SERVERS

Surfshark offers 3200+ servers in 100 countries.

Locations in global regions:

The Americas18
Europe46
Asia Pacific27
Middle East & Africa8

Locations in specific countries:

The US25
The UK4
Australia5
Canada3
The Netherlands1
Germany2