<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Networking · 인재덕</title>
    <link>https://jared.lynskey.co.nz/ko/tags/networking/</link>
    <description>소프트웨어 엔지니어링과 개발 조직 리더십에 대한 이야기. 성과 리뷰, 채용과 팀 확장, CI/CD, 데브옵스 모니터링, 에이전틱 AI. 서울에서 씁니다.</description>
    <generator>Hugo</generator>
    <language>ko</language>
    <copyright>© 2026 인재덕</copyright>
    <lastBuildDate>Wed, 28 Oct 2026 00:00:00 +1300</lastBuildDate>
    <atom:link href="https://jared.lynskey.co.nz/ko/tags/networking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Cloudflare WARP와 Tunnel로 만든 사설 네트워크: 노트북, 폰, 워크스테이션 연결하기</title>
      <link>https://jared.lynskey.co.nz/ko/posts/2026/2026-10-01-cloudflare-warp-dev-network/</link>
      <guid isPermaLink="true">https://jared.lynskey.co.nz/ko/posts/2026/2026-10-01-cloudflare-warp-dev-network/</guid>
      <pubDate>Thu, 01 Oct 2026 00:00:00 +1200</pubDate>
      <dc:creator>Jared Lynskey</dc:creator>
      <category>Cloudflare</category>
      <category>WARP</category>
      <category>Zero Trust</category>
      <category>Cloudflare Tunnel</category>
      <category>Networking</category>
      <category>SSH</category>
      <category>DevOps</category>
      <category>AI Agents</category>
      <category>Ollama</category>
      <category>Mobile Development</category>
      <category>IPv6</category>
      <description>Cloudflare WARP와 Cloudflare Tunnel 두 개(Zero Trust)로 노트북, 5G에 붙은 폰, 사무실 GPU 워크스테이션을 사설 네트워크 하나로 묶은 방법입니다. 고정 사설 IP, 열린 포트 없음, Access 뒤에 둔 dev 서버까지.</description>
      <content:encoded><![CDATA[<p>Cloudflare WARP를 쓰면 포트를 하나도 열지 않고 내 기계들을 사설 네트워크 하나로 묶을 수 있습니다. 닿고 싶은 기계마다 Cloudflare Tunnel(<code>cloudflared</code>)을 돌리고, 각 터널이 사설 IP 대역을 광고하게 한 다음, 노트북과 폰에 WARP 클라이언트를 include 모드로 설치해 Zero Trust 조직에 등록하면 됩니다. 그때부터는 5G에 붙은 폰에서 <code>198.18.42.2</code>로 평범한 연결을 열면 사무실 워크스테이션에 닿습니다. 아래는 제 셋업이 어떻게 짜여 있는지, 그리고 오는 길에 발목을 잡은 네 가지입니다.</p>
<p>제 작업 환경은 좀처럼 한곳에 모이지 않는 기계 세 대입니다. 어디든 들고 다니는 MacBook Air가 있습니다. 사무실에는 devbox라는 워크스테이션이 있는데, 제대로 된 GPU가 달려 있고 Ollama, 파인튜닝 도구, 자체 컨테이너 레지스트리를 갖춘 작은 Kubernetes 클러스터, 그리고 긴 작업을 붙잡고 씨름하도록 놔둔 에이전트가 무엇이든 돌아갑니다. 그리고 폰이 있습니다. 제가 만드는 앱이 실제로 쓰이는 곳이고, 하루 대부분을 wifi가 아니라 모바일 데이터로 보내죠.</p>
<p>오랫동안 이 셋은 서로 제대로 이야기하지 못했습니다. 노트북은 사무실 LAN에 있을 때만 devbox에 닿았고 그 밖에서는 못 닿았습니다. 폰은 노트북과 같은 wifi에 있을 때만 노트북의 dev 서버에 닿았고, 그것도 제가 <code>0.0.0.0</code>에 바인딩하는 걸 잊지 않고 그날 아침 DHCP가 Mac에 준 주소를 직접 쳐 넣었을 때 얘기였습니다. 워크스테이션에서 재미있는 건 전부, 그러니까 Ollama API, 클러스터 대시보드, 트레이스, 레지스트리는 일부러 localhost나 클러스터 네트워크에 바인딩돼 있었습니다. 어느 것도 인터넷에 있을 물건이 아니니까요.</p>
<p>이 글은 Cloudflare WARP와 Cloudflare Tunnel 한 쌍으로 이것들을 어떻게 이었는지, 그게 AI 기능과 모바일 앱을 만드는 방식을 어떻게 바꿨는지, 그리고 저한테 말도 없이 고장 난 몇 가지에 대한 이야기입니다.</p>

<h2 class="relative group">제가 실제로 원한 것
    <div id="제가-실제로-원한-것" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a0%9c%ea%b0%80-%ec%8b%a4%ec%a0%9c%eb%a1%9c-%ec%9b%90%ed%95%9c-%ea%b2%83" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>요구사항으로 적으면 짧습니다.</p>
<ol>
<li>노트북은 씬 클라이언트여야 합니다. GPU나 많은 RAM, 몇 시간의 실행 시간이 필요한 일은 전부 devbox에서 돌아야 하고, 노트북은 사무실에서든 집에서든 카페에서든 똑같은 방식으로 거기에 닿아야 합니다.</li>
<li>폰은 어디서든, 모바일 데이터로, 켜고 끄는 걸 기억해야 하는 VPN 없이 제 dev 서버와 셸에 닿아야 합니다.</li>
<li>시스템이 어떻게 돌아가는지 보는 데 쓰는 것들, 즉 대시보드, 트레이스, <code>docker info</code>, 모델 목록은 저만 닿을 수 있어야 하고, 공개 URL을 절대 가져서는 안 됩니다.</li>
<li>인바운드 포트는 없습니다. 사무실 라우터에도, 집 라우터에도, 어디에도요.</li>
</ol>
<p>네 번째 요구사항이 예전의 답, 즉 포트 포워딩과 동적 DNS 이름을 배제합니다. 잔재주도 상당수 배제되죠. devbox와 노트북 둘 다 제가 통제하지 못하는 NAT 뒤에 있고, 노트북은 몇 시간마다 다른 NAT 뒤에 있습니다.</p>

<h2 class="relative group">이전: SSH 터널 저장소
    <div id="이전-ssh-터널-저장소" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%b4%ec%a0%84-ssh-%ed%84%b0%eb%84%90-%ec%a0%80%ec%9e%a5%ec%86%8c" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>첫 버전은 제가 직접 만든 작은 저장소였고, 지금도 바닥층으로 남아 있습니다. 노트북에서 &ldquo;SSH로 닿는 것들에 깔끔한 이름 붙이기&rdquo; 문제만 풀고, 그 이상은 하지 않습니다. dnsmasq가 <code>*.test</code>에 <code>127.0.0.1</code>로 답하고, Caddy가 호스트명에 따라 로컬 포트로 라우팅하면서 <code>tls internal</code>로 브라우저를 만족시키고, autossh launch agent 묶음이 SSH 포워드를 열어 두었다가 끊기면 다시 잇습니다. 호스트명이 그 물건이 어디 사는지 말해 줍니다.</p>
<table>
	<thead>
			<tr>
					<th>접미사</th>
					<th>의미</th>
					<th>실어 나르는 것</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>*.local.test</code></td>
					<td>이 Mac</td>
					<td>없음, dev 서버입니다</td>
			</tr>
			<tr>
					<td><code>*.ssh.test</code></td>
					<td>서버</td>
					<td>autossh 포워드</td>
			</tr>
			<tr>
					<td><code>*.cloud.test</code></td>
					<td>호스팅된 앱</td>
					<td>호스팅 플랫폼 자체 프록시</td>
			</tr>
	</tbody>
</table>
<p>그래서 <code>https://devbox-ollama.ssh.test/api/tags</code>는 워크스테이션의 모델 목록을 보여 주고, <code>https://api.local.test</code>는 제 기계에서 도는, 지금 작업 중인 앱의 API입니다.</p>
<p><code>.ssh</code>나 <code>.cloud</code> 같은 새 최상위 이름이 아니라 <code>.test</code>의 서브도메인이고, <code>.local</code>도 아닙니다. RFC 6761이 바로 이런 용도로 <code>.test</code>를 예약해 두었고, <code>.local</code>은 mDNS 몫입니다. 그걸 가로채면 Mac에서 Bonjour 탐색이 멈춥니다. dnsmasq가 이미 <code>*.test</code> 전체를 와일드카드로 잡고 있으니 라벨 하나 더 붙이는 데 드는 비용은 없습니다. <code>127.0.0.1</code>을 가리키는 <code>/etc/resolver/test</code> 파일 하나면 되고, 그 뒤로 DNS를 더 건드릴 일은 영영 없습니다.</p>

<h3 class="relative group">존재하지 않는 이름에 HTTPS 붙이기
    <div id="존재하지-않는-이름에-https-붙이기" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a1%b4%ec%9e%ac%ed%95%98%ec%a7%80-%ec%95%8a%eb%8a%94-%ec%9d%b4%eb%a6%84%ec%97%90-https-%eb%b6%99%ec%9d%b4%ea%b8%b0" aria-label="앵커">#</a>
    </span>
    
</h3>
<p>저 이름들은 전부 브라우저가 신뢰하는 인증서로 HTTPS 서비스됩니다. 제 노트북에만 존재하는 호스트명에 그게 된다니 불가능하게 들리죠. Caddy는 자체 내부 인증 기관으로 이걸 해냅니다. 사이트에 <code>tls internal</code>을 넣으면 Caddy는 Let&rsquo;s Encrypt에 요청하는 대신 로컬 CA에서 그 사이트의 인증서를 발급하고, 설치 스크립트가 한 번 실행하는 <code>caddy trust</code>가 그 CA의 루트를 macOS 시스템 키체인(Chrome과 Safari가 읽는 곳)과 Firefox 자체 저장소에 넣습니다. 그다음부터 <code>https://anything.test</code>는 인증서 경고 없이 열리고, 평범한 <code>http://</code>는 그쪽으로 리다이렉트되며, 아무것도 기계 밖으로 나가지 않습니다.</p>
<p>겉모양만의 문제가 아닙니다. 요즘 웹 플랫폼의 상당 부분이 평범한 HTTP에서는 동작을 거부합니다. secure 쿠키, 서비스 워커, 클립보드 API, <code>SameSite=None</code>이 들어간 모든 것이요. 웹 빌드를 평범한 <code>http://localhost</code>에서 테스트하면 실제 HTTPS 도메인에서 나타날 버그가 가려집니다. <code>https://app.local.test</code>에서 테스트하면 그 버그가 제 노트북에서 대신 드러납니다.</p>
<p>사이트 블록 하나입니다. 포트만 빼면 모든 서비스가 똑같습니다.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-caddyfile" data-lang="caddyfile"><span class="line"><span class="cl"><span class="gh">devbox-ollama.ssh.test</span>, <span class="gh">devbox-ollama.test</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">tls</span> <span class="no">internal</span>
</span></span><span class="line"><span class="cl">	<span class="k">import</span> cors
</span></span><span class="line"><span class="cl">	<span class="k">reverse_proxy</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">11435</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">import</span> proxyhdr
</span></span><span class="line"><span class="cl">		<span class="k">transport</span> <span class="s">http</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="k">keepalive</span> <span class="no">off</span>
</span></span><span class="line"><span class="cl">			<span class="k">dial_timeout</span> <span class="mi">5s</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>손이 많이 가는 부분은 두 스니펫이 맡습니다. <code>cors</code>는 <code>*</code>를 보내는 대신 호출한 쪽의 <code>Origin</code>을 그대로 돌려줍니다. 자격 증명이 끼는 순간 <code>*</code>는 허용되지 않기 때문입니다. 그리고 <code>OPTIONS</code> 프리플라이트에는 직접 204로 답해서 업스트림이 신경 쓸 필요가 없게 합니다. <code>proxyhdr</code>는 <code>Host</code> 헤더를 다이얼 주소로 바꿔 씁니다. 라우터 관리 페이지나 Chrome의 원격 디버깅 엔드포인트 같은 까다로운 백엔드는 <code>Host</code>를 검사하는데, 이게 없으면 <code>devbox-ollama.ssh.test</code>를 처음 듣는 이름이라며 거부합니다. Ollama의 자체 origin 검사는 포트와 상관없이 루프백을 받아 주니, <code>Host</code>를 <code>127.0.0.1:11435</code>로 바꿔 쓰면 통과합니다.</p>
<p><code>keepalive off</code>는 제가 틀렸을 법한 부분입니다. 업스트림은 네트워크가 바뀔 때마다 autossh가 허물고 다시 세우는 SSH 포워드입니다. keep-alive가 켜져 있으면 Caddy는 이미 죽은 터널에 대한 풀링된 연결을 쥐고 있다가, 리로드할 때까지 영문 모를 404를 돌려줍니다. 끄면 요청마다 새로 다이얼하는데, 루프백에서는 측정할 만한 비용이 없습니다.</p>
<p>각 서비스는 예전의 평평한 이름(<code>devbox-ollama.test</code>)으로도 답하기 때문에, 접미사 체계 이전의 북마크도 여전히 동작합니다.</p>

<h3 class="relative group">메뉴 막대
    <div id="메뉴-막대" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a9%94%eb%89%b4-%eb%a7%89%eb%8c%80" aria-label="앵커">#</a>
    </span>
    
</h3>
<p>launchd가 포워드 십여 개를 열어 두고 있으니 제가 계속 던진 질문은 &ldquo;살아 있나?&ldquo;였고, 그 답은 세 군데에 흩어져 있었습니다. <code>launchctl list</code>, <code>lsof</code>, 그리고 <code>curl</code>. 그래서 작은 메뉴 막대 플러그인으로 한곳에 모았습니다. 호스트명마다 옆에 점이 하나씩 붙습니다.</p>
<ul>
<li>🟢 서비스가 터널을 통한 요청에 답했습니다</li>
<li>🟡 터널은 열려 있지만 그 뒤의 서비스가 조용합니다</li>
<li>🔴 로컬 포트에서 아무것도 듣고 있지 않으니, 터널 자체가 죽었습니다</li>
</ul>
<p>쓸모 있는 건 노란색입니다. 초록/빨강 검사로는 &ldquo;SSH 포워드가 죽었다&quot;와 &ldquo;반대편에서 Ollama가 뻗었다&quot;를 구분할 수 없고, 둘은 고치는 방법이 전혀 다릅니다. 플러그인은 자체 서비스 목록을 따로 두지 않고 다른 것들과 같은 프록시 설정과 SSH 설정을 읽으니, 거기에 서비스를 추가하면 메뉴에도 추가됩니다.</p>
<p>첫 버전은 욕심이 과했습니다. 10초마다 새로 고치면서 서비스마다 프로세스를 몇 개씩 띄워 한 번 돌 때 70개쯤 됐고, macOS는 곧바로 이 플러그인을 &ldquo;에너지를 많이 사용하는 앱&quot;에 올렸죠. 한 번 돌 때 스냅샷을 한 번만 뜨고 몇 분 간격으로 새로 고치게 바꾸니 코어 하나의 0.1% 정도로 내려왔습니다. 배터리를 갉아먹는 상태 표시는 도움이 안 되니, 처음부터 비용을 따져 둘 만합니다.</p>
<p>구멍이 하나 있었는데, 하필 중요한 구멍이었습니다. devbox에는 공개 이름이 없습니다. 그 SSH 포워드는 <code>192.168.x</code> 주소로 다이얼했으니, 노트북이 사무실 LAN에 있을 때만 동작했습니다. 사무실을 벗어나면 메뉴 막대가 빨개진 채로 그대로였고, 노트북을 아끼려고 워크스테이션으로 옮겨 둔 모든 것이 정확히 제가 그 옆에 앉아 있지 않을 때 닿지 않았습니다.</p>

<h2 class="relative group">방향을 제대로 잡은 터널 두 개
    <div id="방향을-제대로-잡은-터널-두-개" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b0%a9%ed%96%a5%ec%9d%84-%ec%a0%9c%eb%8c%80%eb%a1%9c-%ec%9e%a1%ec%9d%80-%ed%84%b0%eb%84%90-%eb%91%90-%ea%b0%9c" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>해결책은 세 부분이고, 앞의 둘이 Cloudflare Tunnel입니다.</p>
<p>Cloudflare Tunnel은 <code>cloudflared</code>가 Cloudflare 엣지로 아웃바운드 연결을 붙잡고 있는 것입니다. Cloudflare는 그 연결로 요청을 내려보내니, NAT가 몇 겹이든 그 뒤의 기계가 라우터에서 아무것도 듣지 않고도 닿을 수 있게 됩니다. 노트북을 따라 호텔 wifi로 가고, CGNAT에서도 살아남습니다.</p>
<p>저는 기계마다 하나씩 두 개를 돌리는데, 그 이유는 한 문장 들일 만합니다. 뻔한 지름길은 노트북에 터널 하나를 두고, 사무실 LAN에 있는 devbox의 SSH 포트를 가리키는 ingress 규칙을 하나 더 넣는 것이었습니다. 그러면 devbox에는 아무것도 설치할 필요가 없습니다. 대신 노트북을 거쳐 라우팅되는데, 노트북은 사무실을 떠나는 기계입니다. 고치려던 바로 그 상황에서 고장 났을 겁니다. devbox는 제자리에 있으니, devbox가 엣지로 가는 자기 연결을 쥡니다.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># config.yml on devbox (runs as a systemd service)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">auto       </span><span class="w"> </span><span class="c"># prefer QUIC, fall back to HTTP/2 over TCP 443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">ha-connections</span><span class="p">:</span><span class="w"> </span><span class="m">4</span><span class="w">     </span><span class="c"># mains-powered, its job is to stay reachable</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">warp-routing</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">connectTimeout</span><span class="p">:</span><span class="w"> </span><span class="l">5s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">ingress</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">ssh-devbox.example.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">tcp://127.0.0.1:22</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">http_status:404</span></span></span></code></pre></div></div>
<p><code>ssh://</code>가 아니라 <code>tcp://</code>라는 건 헷갈리기 쉬운 부분입니다. <code>ssh://</code>는 Cloudflare의 브라우저 렌더링 터미널을 선택하는데, 이건 스트림을 웹 페이지용으로 감쌉니다. 평범한 <code>ssh</code> 클라이언트를 거기로 통과시키면 배너까지는 받고 키 교환에서 죽습니다. <code>tcp://</code>는 <code>cloudflared access ssh</code>가 기대하는 평범한 바이트 파이프이고, 덤으로 <code>scp</code>, <code>rsync</code>, SSH 위의 git, 포트 포워드까지 실어 나릅니다.</p>
<p>그 마지막 부분이 SSH 계층의 구멍을 막았습니다. 이제 SSH 설정이 연결마다 경로를 고릅니다.</p>
<div class="highlight-wrapper"><pre tabindex="0"><code class="language-sshconfig" data-lang="sshconfig">Match originalhost devbox !exec &#34;nc -z -G 1 &lt;office-lan-ip&gt; 22 &gt;/dev/null 2&gt;&amp;1&#34;
    ProxyCommand cloudflared access ssh --hostname ssh-devbox.example.com ...</code></pre></div>
<p>사무실 LAN에서는 탐침이 성공하고 SSH가 한 홉으로 직접 갑니다. 그 밖의 어디서든 탐침이 실패하고 SSH는 Cloudflare를 거치는데, Access 서비스 토큰으로 인증하니 브라우저 로그인이 끼어들지 않습니다. <code>Match host</code>가 아니라 <code>Match originalhost</code>입니다. <code>host</code>는 <code>HostName</code>이 치환된 뒤에 매칭되니, 그 시점엔 이름이 이미 IP라서 블록이 절대 발동하지 않습니다. 결과적으로 <code>devbox-ollama.ssh.test</code>가 사무실에서도, 집에서도, 기차에서도 동작하고, 메뉴 막대의 점은 초록으로 남습니다.</p>
<p>노트북의 터널은 반대 방향으로 갑니다. Mac의 dev 서버에 진짜 공개 HTTPS 호스트명을 줍니다. 작업 중인 앱마다 API, WebSocket 서버, 웹 빌드요. 전부 Cloudflare Access 뒤에 있는데, 이건 뒤에서 다시 다루겠습니다. 이걸 무모한 게 아니라 안전한 것으로 만드는 부분이니까요.</p>
<p>메뉴 막대도 두 터널을 알게 됐는데, 탐침으로는 할 수 없었습니다. 인바운드 터널에는 확인할 로컬 포트가 없고, 커넥터 둘 중 하나는 노트북에서 돌지도 않으며, 뻔한 테스트인 <code>ssh-devbox.example.com</code>에 curl 날리기는 커넥터가 붙어 있든 말든 Cloudflare 엣지가 답하니, 죽은 터널에서도 초록으로 읽힐 겁니다. launchd도 나을 게 없습니다. <code>cloudflared</code>는 엣지 연결이 전부 끊긴 채로 &ldquo;loaded, exit 0&rdquo; 상태로 앉아 있거든요. 그래서 터널 상태는 각 터널에 건강한 커넥터가 붙어 있는지 Cloudflare API에 물어서 확인합니다. <code>ssh</code>가 닿을지를 결정하는 게 바로 그쪽이니까요. API에 닿지 못하면 빨갛게 그리지 않고 그 부분을 통째로 뺍니다. 메뉴는 힐끗 보고 읽는 것이라, 거기서 잘못된 경보는 빠진 한 줄보다 비쌉니다.</p>

<h2 class="relative group">세 번째 부분: WARP가 이걸 네트워크로 만듭니다
    <div id="세-번째-부분-warp가-이걸-네트워크로-만듭니다" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%84%b8-%eb%b2%88%ec%a7%b8-%eb%b6%80%eb%b6%84-warp%ea%b0%80-%ec%9d%b4%ea%b1%b8-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac%eb%a1%9c-%eb%a7%8c%eb%93%ad%eb%8b%88%eb%8b%a4" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>호스트명이 붙은 터널은 HTTPS로 말하는 것, 그리고 <code>cloudflared</code>를 돌릴 수 있는 기계에서의 SSH에는 훌륭합니다. 폰은 못 돌립니다. 게다가 터널 호스트명은 TCP 엔드포인트가 아닙니다. Cloudflare 엣지는 거기서 HTTPS와 WebSocket만 종단하니, <code>ssh.example.com</code>의 22번 포트는 닫혀 있고 Access를 아무리 만지작거려도 열리지 않습니다.</p>
<p>그게 WARP의 일입니다. Cloudflare One Agent(엔터프라이즈용 WARP 클라이언트입니다. 조직에 가입할 수 없는 일반 소비자용 &ldquo;1.1.1.1&rdquo; 앱이 아니고요)를 노트북과 폰에 설치해 제 Zero Trust 조직에 등록했습니다. 각 터널이 사설 경로를 광고하면, WARP를 돌리는 기기는 그 주소로 평범한 소켓을 열어 올바른 기계에 닿을 수 있습니다. &ldquo;이 서비스에 이름으로 닿기&quot;가 아니라 &ldquo;이 기계들이 나와 같은 네트워크에 있다&quot;가 되는 거죠.</p>
<table>
	<thead>
			<tr>
					<th>주소</th>
					<th>기계</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>198.18.42.1</code> / <code>fd12:3456:789a::1</code></td>
					<td>MacBook Air</td>
			</tr>
			<tr>
					<td><code>198.18.42.2</code> / <code>fd12:3456:789a::2</code></td>
					<td>devbox</td>
			</tr>
			<tr>
					<td><code>198.18.42.3</code> / <code>fd12:3456:789a::3</code></td>
					<td>두 번째 Mac</td>
			</tr>
	</tbody>
</table>
<p>이 주소들은 부팅 때 만들어지는 각 기계의 루프백 별칭이라, DHCP나 제가 어떤 라우터 뒤에 있는지와 아무 상관이 없습니다. <code>198.18.42.2</code>는 사무실에서도, 집에서도, 5G에 붙은 폰에서도 devbox입니다. Mac의 진짜 LAN 주소는 옮길 때마다 바뀌지만, 이 주소는 절대 바뀌지 않습니다.</p>
<p>스플릿 터널은 <strong>include 모드</strong>이고, 저 경로들(과 WARP가 스스로 쓰는 Cloudflare 대역)만 들어 있습니다. 이게 클라이언트를 켜 두고 살 수 있게 만드는 부분입니다. 기본값은 exclude 모드인데, WARP가 사설 대역 목록을 뺀 모든 것을 실어 나르니 폰이 보내는 모든 바이트가 Cloudflare를 돌아갑니다. 배터리와 지연 시간 비용이 실제로 있고, 결국 필요할 때만 켜게 됐을 만큼입니다. 그러면 요점이 무너지죠. include 모드에서는 제 기계 세 대로 가는 트래픽만 WARP를 거치고 나머지는 전부 평소 경로로 손대지 않은 채 나갑니다. 그래서 클라이언트는 그냥 켜진 채로 있습니다. 노트북의 <code>warp-cli status</code>는 하루 종일 <code>Connected</code>라고 하고, 저는 신경 쓰지 않습니다.</p>
<p>전송 방식은 UDP 2408 위의 WireGuard가 아니라, UDP 443 위의 HTTP/3에 HTTP/2 폴백이 붙은 MASQUE로 해 두었습니다. 일부 통신사와 게스트 네트워크는 2408을 막지만, 443을 막는 곳은 거의 없습니다. 제 조직 정책에서는 MASQUE에 양자내성 키 합의도 켜져 있는데, 찾아서 켠 건 아니지만 마다할 이유도 없죠.</p>

<h2 class="relative group">왜 198.18이고, 왜 IPv6 주소가 있는지
    <div id="왜-19818이고-왜-ipv6-주소가-있는지" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%99%9c-19818%ec%9d%b4%ea%b3%a0-%ec%99%9c-ipv6-%ec%a3%bc%ec%86%8c%ea%b0%80-%ec%9e%88%eb%8a%94%ec%a7%80" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>주소가 좀 이상해 보이는데, 처음 고른 주소는 배울 게 있는 방식으로 틀렸습니다.</p>
<p>첫 시도는 <code>10.10.0.1</code>이었습니다. 다들 손이 가는 주소니까요. 이건 두 스플릿 터널 모드 모두에서 실패합니다. exclude 모드에서는 WARP의 기본 목록이 RFC 1918 대역 전부와 <code>100.64.0.0/10</code>을 제외하니, 클라이언트가 그 주소로 가는 트래픽을 기기를 떠나기도 전에 버렸을 겁니다. include 모드에서는 제가 어쩌다 붙는 실제 <code>10.x</code> 네트워크와 충돌했을 겁니다. 카페, 코워킹 스페이스, 그리고 꽤 많은 사무실이 딱 그 대역을 씁니다. <code>198.18.0.0/15</code>는 RFC 2544 벤치마킹 대역입니다. 예약돼 있고, 공용 인터넷에서 라우팅되는 일이 없고, WARP의 exclude 목록에 없으며, 평범한 네트워크라면 쓰지 않습니다. IPv6 주소가 ULA(<code>fd00::/8</code>)인 것도 같은 이유입니다.</p>
<p>IPv6가 애초에 왜 있는지가 더 재미있는 이야기입니다. v4 주소가 동작하자 폰에서 wifi로 테스트해 봤고, 잘 됐고, 끝났다고 선언했습니다. 5G에서는 안 됐습니다. Agent는 <em>connected</em>라고 했고, 터널은 멀쩡했고, Access도 괜찮았습니다. wifi 테스트가 그 전부를 증명했으니까요. 문제는 요즘 모바일 네트워크가 대부분 IPv6 전용이라는 점이었습니다. 폰에는 네이티브 IPv4가 아예 없었고, v4 리터럴에는 통신사의 464XLAT 변환기를 통해 닿고 있었는데, include 목록에 v4 접두사만 있으면 그 변환기는 터널 <em>바깥</em>에 놓입니다. 트래픽은 <code>198.18.0.0/15</code>가 라우팅되지 않는 공용 인터넷으로 나갔고, 소리 없이 버려졌습니다. 폰에도 오류가 없고, 커넥터 로그에도 아무것도 없었습니다.</p>
<p>해결책은 모든 기계에 폰이 IPv6로 네이티브하게 닿을 수 있는 두 번째 주소를 주고, 그걸 경로와 include 목록에 추가하는 것입니다. 이제 모바일 데이터에서 폰의 SSH 클라이언트가 실제로 쓰는 건 <code>fd12:3456:789a::</code> 주소입니다.</p>

<h2 class="relative group">오프로딩: 단말기로서의 노트북
    <div id="오프로딩-단말기로서의-노트북" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%98%a4%ed%94%84%eb%a1%9c%eb%94%a9-%eb%8b%a8%eb%a7%90%ea%b8%b0%eb%a1%9c%ec%84%9c%ec%9d%98-%eb%85%b8%ed%8a%b8%eb%b6%81" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>이 셋업 전체가 존재하는 이유가 이 부분입니다.</p>
<p><strong>모델과 파인튜닝.</strong> Ollama는 devbox에서 돌고 <code>127.0.0.1:11434</code>에 바인딩됩니다. 인터넷은 고사하고 사무실 LAN의 다른 기계에서도 보이지 않습니다. 노트북에서는 <code>https://devbox-ollama.ssh.test</code>로 나타나고, 포트 번호만 원하는 도구에는 그냥 포트로 나타납니다.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">OLLAMA_HOST</span><span class="o">=</span>127.0.0.1:11435 ollama list</span></span></code></pre></div></div>
<p>11434가 아니라 11435인 건 일부러입니다. 11434는 Ollama 자체 기본값이라, 노트북에서도 로컬 Ollama를 돌리게 되면 둘이 포트를 두고 경쟁하고, 어느 쪽이 먼저 떴느냐에 따라 &ldquo;로컬&rdquo; 쪽에서 devbox의 답을 소리 없이 받게 됩니다.</p>
<p>실제 효과는, AI 기능을 만들 때 그 기능이 호출하는 모델이 제가 어디에 있든 노트북이 아니라 워크스테이션 GPU라는 점입니다. 평가 실행, 문서 한 무더기 임베딩, 파인튜닝은 devbox에서 돌고, 노트북 팬은 조용합니다. 에이전트를 프로토타이핑할 때는 워크스테이션의 로컬 모델을 가리키게 해서 API 청구서 없이 툴 호출 반복을 마음껏 태울 수 있고, 루프가 제대로 잡히면 호스팅 모델로 바꾸면 됩니다.</p>
<p><strong>오래 도는 에이전트.</strong> 한 시간 도는 에이전트 세션이 제 노트북 덮개가 열려 있는지에 달려 있어서는 안 됩니다. 대신 devbox에서 돌리면 노트북은 그저 거기로 난 창문입니다. 덮개를 닫고, 나중에 어디서든, 혹은 폰에서 <code>ssh devbox</code>를 하면 여전히 거기 있습니다. 터널 이전에는 이게 사무실에서만 됐는데, 사무실은 정확히 이게 필요 없는 곳이었죠.</p>
<p><strong>빌드와 클러스터.</strong> devbox의 클러스터에는 자체 레지스트리가 있어서, 이미지를 노트북에서 호텔 wifi로 올리는 대신 워크스테이션에서, 실행될 곳 바로 옆에서 빌드하고 푸시할 수 있습니다. 클러스터 대시보드, ingress 대시보드, 레지스트리 UI는 노트북에서 전부 <code>*.ssh.test</code> 호스트명입니다.</p>
<p><strong>모바일 루프.</strong> 폰은 노트북과 같은 사설 네트워크에 있고, 노트북의 dev 서버에는 Access 뒤의 공개 호스트명도 있습니다. 그래서 앱의 네이티브 빌드를 들고 건물 밖으로 나가 5G에서 써도, 제 책상에서 도는 API와 통신합니다. 제가 devbox에 띄워 두었다면 그쪽과 통신하고요. 실제 모바일 네트워크 위의 실제 기기로 피드백 루프를 돌리려면 예전에는 공유 스테이징 서버에 배포해야 했습니다. 지금은 파일을 저장하면 됩니다.</p>
<p>앱 버그로 착각하고 디버깅하기 전에 알아 둘 만한 함정이 하나 있습니다. Access는 WebSocket 호스트명도 보호하는데, 네이티브 WebSocket 클라이언트는 브라우저가 아닙니다. <code>CF_Authorization</code> 쿠키를 들고 있지 않으니, 네이티브 빌드가 WebSocket 서버에 연결하면 엣지에서 403으로 거부되는데, 이게 내 서버가 내는 오류와는 전혀 닮지 않았습니다. 브라우저 탭은 로그인할 때 받은 쿠키를 이미 들고 있으니 괜찮습니다. 브라우저가 아닌 모든 것(네이티브 앱, 스크립트, dev API를 호출하는 에이전트)에 대한 답은 Access <strong>서비스 토큰</strong>이고, 헤더 두 개로 보냅니다.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">CF-Access-Client-Id:     &lt;client_id&gt;
</span></span><span class="line"><span class="cl">CF-Access-Client-Secret: &lt;client_secret&gt;</span></span></code></pre></div></div>
<p>토큰은 그 자체로는 아무 권한도 주지 않습니다. Access는 정책에 그 토큰이 명시된 앱에서만 받아 주니, 토큰이 닿는 범위는 정확히 dev 호스트명 목록이고 그보다 넓지 않습니다. 저는 그 정책을 <code>allow</code>가 아니라 <code>non_identity</code> 결정으로 분류해 두는데, 그러면 감사 로그에서 로그인한 사람이 아니라 bearer 시크릿으로 보입니다.</p>

<h2 class="relative group">인터넷은 절대 보지 못하는 통계
    <div id="인터넷은-절대-보지-못하는-통계" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%b8%ed%84%b0%eb%84%b7%ec%9d%80-%ec%a0%88%eb%8c%80-%eb%b3%b4%ec%a7%80-%eb%aa%bb%ed%95%98%eb%8a%94-%ed%86%b5%ea%b3%84" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>제가 원한 것의 나머지 절반은 가시성이었습니다. 시스템이 어떻게 돌아가는지 알려 주는 것 대부분은 공개돼 있지 않은 게 맞습니다. devbox에서는 이런 것들입니다.</p>
<ul>
<li>ingress 프록시 대시보드, 그리고 그 트레이스가 담긴 트레이싱 UI</li>
<li>Kubernetes 클러스터용 대시보드</li>
<li>컨테이너 레지스트리 UI(읽기 전용)</li>
<li>Ollama 모델 목록과 지금 로드된 것</li>
<li><code>docker info</code>와 컨테이너 통계</li>
</ul>
<p>이 중 어느 것도 공개 호스트명이 없고, 앞으로도 없을 겁니다. 루프백이나 클러스터 서비스 IP에 바인딩돼 있고, 그 자체가 터널을 타는 SSH 포워드로 닿습니다. 폰의 모니터링 앱은 WARP 너머 SSH로 <code>docker info --format '{{json .}}'</code>를 읽으니, 컨테이너가 떠 있는지 아니면 뭔가 메모리를 다 먹어 치웠는지 어디서든 볼 수 있습니다.</p>
<p>그 앱 덕분에 언급할 만한 작은 버그를 하나 찾았습니다. Mac의 터널용 sshd가 디버깅하던 시절 그대로 <code>LogLevel DEBUG2</code>였습니다. <code>-e</code>를 주면 sshd는 stderr로 로그를 남기는데, 세션에서는 그 stderr가 <em>곧</em> SSH 채널의 stderr입니다. 모든 명령의 출력 끝에 <code>debug2: do_setup_env: set TMPDIR</code>가 붙어서 돌아왔고, 두 스트림을 합치는 폰 앱은 유효한 JSON 뒤에 로그 한 줄이 붙은 걸 받아 파싱에 실패하고는 통째로 오류로 보여 줬습니다. <code>LogLevel INFO</code>로 고쳤습니다. 디버깅이 끝나면 로그 레벨을 되돌려 놓으세요.</p>
<p>이 네트워크에 <em>올리지 않는</em> 것도 똑같이 의도적입니다. 예전 autossh 터널은 제가 관리를 돕는 남의 네트워크의 라우터 몇 대에도 닿습니다. 그것들에는 공개 호스트명도, WARP 경로도 주지 않습니다. 인터넷에 나온 라우터 관리 페이지는 로그인 뒤에 있어도 골칫거리고, 제가 넓힐 수 있는 제 네트워크도 아니니까요.</p>

<h2 class="relative group">Access는 선택이 아닙니다
    <div id="access는-선택이-아닙니다" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#access%eb%8a%94-%ec%84%a0%ed%83%9d%ec%9d%b4-%ec%95%84%eb%8b%99%eb%8b%88%eb%8b%a4" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>Cloudflare Tunnel 호스트명은 DNS 레코드가 생기는 순간 공용 인터넷에 올라갑니다. 앞에 방화벽이 없습니다. 포트를 열지 않는다는 게 애초에 요점이니까요. 보호는 Cloudflare 엣지에서 와야 하고, 그게 Access가 하는 일입니다. 방문자가 누구인지 증명하기 전까지는 요청을 아예 전달하지 않으니, 인증되지 않은 스캐너는 노트북에 절대 닿지 못합니다. 이게 중요한 건 이것들이 dev 서버이기 때문입니다. 설정값이 그대로 드러나는 디버그 모드 트레이스백, 열려 있는 JavaScript 번들러. 이 호스트명들 뒤에 있는 것 중 인터넷을 마주하도록 만들어진 건 하나도 없습니다.</p>
<p>정책은 제 이메일 주소들만 허용하고 나머지는 아무것도 허용하지 않으며, 증명 방법은 이메일 일회용 PIN과 SSO 두 가지입니다. 세션은 8시간인데, 현실적인 위협은 누군가 PIN을 무차별 대입하는 게 아니라 하루짜리 쿠키를 품은 채 카페에 열어 두고 온 노트북이기 때문입니다.</p>
<p>SSH는 서로의 존재를 모르는 두 시스템이 두 번 인증합니다. Access는 TCP 스트림이 sshd에 닿아도 되는지를 정하고, sshd는 그래도 제 키를 요구합니다. 어느 하나를 잃어도 기계가 열리지는 않습니다. Mac의 터널용 sshd는 Cloudflare의 SSH CA도 신뢰해서, Access가 제 SSO 세션으로 발급한 단기 인증서로 저를 로그인시킬 수 있습니다. 그러면서 <code>authorized_keys</code>도 나란히 동작하니, Access 설정이 망가져도 제 노트북에서 제가 쫓겨나는 일은 없습니다.</p>
<p>제일 마음에 드는 건 작은 부분입니다. 노출은 세 가지가 맞아떨어질 때 일어납니다. DNS 레코드, 돌고 있는 커넥터, 활성 상태의 존. 이 셋은 제가 통제하지 못하는 순서로, 서로 다른 시점에 참이 됩니다. 존은 네임서버를 바꾸고 얼마 뒤에 혼자 활성으로 바뀌는데, Mac이 잠들어 있을 때일 수도 있습니다. 그래서 launch agent는 <code>cloudflared</code>를 직접 실행하지 않습니다. 대신 터널 자체 설정에서 호스트명을 읽어 Access API에 어느 것이 보호되고 있는지 묻고, 하나라도 빠져 있으면 시작을 거부하는 사전 점검을 돌립니다.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">HOSTNAMES</span><span class="o">=</span><span class="k">$(</span>grep -E <span class="s1">&#39;^\s*-\s*hostname:&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG</span><span class="s2">&#34;</span> <span class="p">|</span> sed -E <span class="s1">&#39;s/.*hostname:\s*//&#39;</span> <span class="p">|</span> sort -u<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">PROTECTED</span><span class="o">=</span><span class="k">$(</span>curl -fsS -H <span class="s2">&#34;Authorization: Bearer </span><span class="nv">$CLOUDFLARE_API_TOKEN</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="s2">&#34;https://api.cloudflare.com/client/v4/accounts/</span><span class="nv">$CLOUDFLARE_ACCOUNT_ID</span><span class="s2">/access/apps?per_page=100&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="p">|</span> python3 -c <span class="s1">&#39;import sys,json; print(&#34;\n&#34;.join(a.get(&#34;domain&#34;,&#34;&#34;) for a in json.load(sys.stdin)[&#34;result&#34;]))&#39;</span><span class="k">)</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="o">||</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&#34;could not reach the Access API. refusing (fail closed).&#34;</span><span class="p">;</span> <span class="nb">exit</span> 1<span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> h in <span class="nv">$HOSTNAMES</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    grep -qxF <span class="s2">&#34;</span><span class="nv">$h</span><span class="s2">&#34;</span> <span class="o">&lt;&lt;&lt;</span><span class="s2">&#34;</span><span class="nv">$PROTECTED</span><span class="s2">&#34;</span> <span class="o">||</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&#34;NOT starting: </span><span class="nv">$h</span><span class="s2"> has no Access app&#34;</span><span class="p">;</span> <span class="nb">exit</span> 1<span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span>
</span></span><span class="line"><span class="cl"><span class="nb">exec</span> cloudflared tunnel --config <span class="s2">&#34;</span><span class="nv">$CONFIG</span><span class="s2">&#34;</span> run</span></span></code></pre></div></div>
<p>launch agent에는 <code>KeepAlive</code>가 걸려 있어서, 거부되면 30초마다 알아서 재시도하고 Access 앱이 생기면 터널이 혼자 올라옵니다. 닫힌 채로 실패하면 장애를 치르고, 열린 채로 실패하면 노출을 치릅니다. 둘 중 어느 쪽을 해명하고 싶은지는 압니다.</p>

<h2 class="relative group">발목을 잡은 네 가지
    <div id="발목을-잡은-네-가지" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b0%9c%eb%aa%a9%ec%9d%84-%ec%9e%a1%ec%9d%80-%eb%84%a4-%ea%b0%80%ec%a7%80" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>위의 모든 게 지금은 동작합니다. 여기까지 오는 동안 넷 중 셋은 패턴이 같았습니다. 고장 난 부분은 어디에도 오류를 내지 않았고, 제 눈에 보이는 부분은 전부 정상이라고 보고했습니다.</p>
<p><strong>경로와 include 목록은 서로 다른 목록입니다.</strong> 터널 경로는 Cloudflare가 어떤 주소를 올바른 커넥터로 실어 나를 <em>의향</em>을 갖게 합니다. WARP include 목록은 클라이언트가 애초에 그걸 <em>보내게</em> 만드는 것입니다. devbox가 폰에서 닿지 않았는데, 경로는 있었지만 include 목록에는 여전히 Mac의 주소만 있었기 때문입니다. 폰은 패킷을 로컬에서 버렸고, 커넥터는 흐름을 보지 못했고, 모든 대시보드는 초록이었습니다. 새 기계를 들일 때마다 주소를 양쪽 모두에 추가해야 합니다.</p>
<p><strong>IPv6 전용 모바일 네트워크의 IPv4 리터럴.</strong> 위에서 다뤘습니다. wifi에서는 되고, 5G에서는 안 되고, 오류는 없습니다. WARP 경로가 wifi에서는 되는데 모바일 데이터에서 안 되고 Agent가 connected로 나온다면, 터널이 아니라 라우팅 문제입니다.</p>
<p><strong>cloudflared 뒤의 macOS sshd.</strong> macOS는 sshd를 launchd 소켓 활성화로 띄웁니다. 연결마다 수명이 짧은 <code>sshd -i</code>가 하나씩 뜨는 식이죠. cloudflared 뒤에서는 배너가 클라이언트에 닿은 다음, 클라이언트의 식별 문자열이 돌아오기 전에 스트림이 끊겨서, 모든 로그인이 <code>kex_exchange_identification</code>에서 죽습니다. 양쪽 끝에서 확인했고, 평범한 TCP 릴레이로도 재현해서 Cloudflare 탓이 아님을 확인했습니다. 해결책은 <code>127.0.0.1:2222</code>와 WARP 루프백 주소에서 제 사용자로 도는 두 번째 독립 <code>sshd -D</code>인데, 오직 터널의 origin 노릇을 하려고 존재합니다. 시스템 설정의 원격 로그인은 건드리지 않았습니다. 평범하게 오래 사는 sshd를 쓰는 Linux인 devbox에는 이 문제가 애초에 없었습니다.</p>
<p><strong>더는 존재하지 않는 설정 필드.</strong> 예전 예제에는 터널 설정에 <code>warp-routing: enabled: true</code>가 있습니다. cloudflared 2026.8은 그 필드를 대놓고 거부합니다. WARP 라우팅은 블록이 있고 경로가 터널을 가리키기만 하면 켜집니다. 이건 적어도 오류를 냈는데, 다른 셋을 겪은 뒤라 거의 너그럽게 느껴졌습니다.</p>

<h2 class="relative group">무엇이 바뀌었나
    <div id="무엇이-바뀌었나" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%ac%b4%ec%97%87%ec%9d%b4-%eb%b0%94%eb%80%8c%ec%97%88%eb%82%98" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>솔직하게 요약하면, 하드웨어가 어디 있느냐에 따라 일할 곳을 고르는 걸 그만뒀습니다. 노트북은 배터리가 오래가는 좋은 키보드와 좋은 화면이고, 그 이상일 필요가 없습니다. 워크스테이션은 제가 어디에 있든 무거운 일을 맡습니다. 폰은 사무실 wifi에 묶인 무언가가 아니라 실제 네트워크 위의 실제 테스트 기기입니다. 그리고 시스템이 뭘 하는지 보는 데 쓰는 부분들은 저에게는 클릭 한 번 거리에 있고, 다른 누구에게는 존재하지 않습니다.</p>
<p>이 규모면 Cloudflare의 무료 Zero Trust 플랜에 들어갑니다. 제가 치른 건 시간, 그리고 써 두길 잘했다 싶은 README 하나입니다. 위에 적은 실패는 하나같이 두 번째에도 새로운 미스터리였을 테니까요.</p>
<p>비슷한 걸 고민하고 있다면, 여러분의 셋업에 이런 질문을 던져 보겠습니다.</p>
<ol>
<li>노트북이 언제나 닿을 수 있는 유일한 기계라는 이유만으로 노트북에서 돌고 있는 건 무엇인가요?</li>
<li>폰이 사무실 wifi에서만이 아니라 모바일 데이터로도 dev 서버에 닿나요? wifi 말고 5G에서 테스트해 보세요.</li>
<li>밖에서 보기 쉬운 방법이 그것뿐이라서 공개된 대시보드는 어느 것인가요? 하나하나가 사설 경로로 옮길 후보입니다.</li>
<li>내일 터널 호스트명이 Access 앱 없이 올라온다면, 무엇이 그걸 막나요? 답이 &ldquo;제가 기억하겠죠&quot;라면 사전 점검을 작성하세요.</li>
<li>여러분의 사설 주소는 여러분이 드나드는 네트워크가 절대 쓰지 않을 대역에 있나요?</li>
</ol>
]]></content:encoded>
      <media:content url="https://jared.lynskey.co.nz/en/posts/2026/2026-10-01-cloudflare-warp-dev-network/featured.jpg" medium="image" type="image/jpeg" />
    </item>
    <item>
      <title>커피챗이란? 면접과의 차이, 복장, 질문 리스트</title>
      <link>https://jared.lynskey.co.nz/ko/posts/2024/2024-07-12-coffee-chats/</link>
      <guid isPermaLink="true">https://jared.lynskey.co.nz/ko/posts/2024/2024-07-12-coffee-chats/</guid>
      <pubDate>Fri, 12 Jul 2024 00:30:03 +0000</pubDate>
      <dc:creator>Jared Lynskey</dc:creator>
      <category>Engineering Manager</category>
      <category>Team</category>
      <category>People</category>
      <category>Team Size</category>
      <category>Scaling</category>
      <category>Efficiency</category>
      <category>Talent Scouting</category>
      <category>Coffee Chat</category>
      <category>Recruitment</category>
      <category>Hiring</category>
      <category>Culture Fit</category>
      <category>Networking</category>
      <description>커피챗은 카페나 화상 통화로 30~45분 정도 가볍게 이야기하며 더 깊은 대화를 나눌 가치가 있는지 서로 확인하는 자리입니다. 면접이 아닙니다. 커피챗이 개발자를 만나는 제일 좋은 방법이 된 이유, 제가 진행하는 방식과 물어볼 만한 질문, 초대받은 쪽이라면 뭘 입고 무슨 이야기를 하면 좋은지, 그리고 흔히 망치는 방식까지 적었습니다.</description>
      <content:encoded><![CDATA[<p>정말 채용하고 싶은 개발자는 구직 사이트에 없습니다. 눈앞의 프로덕트를 만드는 데 몰두해 있고, 지금 직장에 그럭저럭 만족하고, 리크루터 메시지에는 (당연하게도) 경계심을 갖고 있죠. 올해 엔지니어링 매니지먼트 쪽으로 옮기고 나서, 그런 사람들을 만나기 위해 제일 의지하게 된 도구는 민망할 만큼 단순합니다. 커피 한 잔이요.</p>
<p>커피챗은 30~45분짜리 가벼운 대화입니다. 카페든 화상 통화든 상관없습니다. 화이트보드도, 면접관 패널도, 함정 질문도 없습니다. 저는 우리가 뭘 왜 만드는지 이야기하고, 상대는 지금 뭘 하고 있고 다음에 뭘 원하는지 이야기합니다. 그것만으로도 더 깊은 대화가 의미 있을지 양쪽 다 알게 되죠. 채용은 선발 문제라기보다 매칭 문제이고, 매칭에 필요한 정보를 교환하는 데 이보다 빠른 방법을 저는 모릅니다.</p>

<h4 class="relative group">왜 계속하는가
    <div id="왜-계속하는가" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%99%9c-%ea%b3%84%ec%86%8d%ed%95%98%eb%8a%94%ea%b0%80" aria-label="앵커">#</a>
    </span>
    
</h4>
<p>저는 이 대화를 &ldquo;채용 활동&quot;이라고 생각하는 걸 그만뒀습니다. 그냥 대화입니다. 그리고 그중 몇 개가 잊을 만하면 채용으로 이어집니다. 상대의 상황이 바뀐 18개월 뒤에 성사되기도 하고요. 좋은 채용을 꾸준히 만들어내는 파이프라인은 채용 공고가 아니라 이런 관계의 축적으로 이루어져 있습니다.</p>
<p>직무 기술서 문제도 해결해 줍니다. JD는 어쩔 수 없이 일반적으로 쓰입니다. 커피를 사이에 두면 후보자가 정말 궁금한 걸 물을 수 있습니다. 첫 6개월에 뭘 해내면 성공인지, 누구와 일하게 되는지, 팀이 지금 씨름 중인 제일 골치 아픈 기술 문제가 뭔지. 이런 질문에 솔직한 답을 들은 사람은 자기와 맞는지 스스로 잘 판단합니다.</p>
<p>그리고 커피챗은 문화를 &ldquo;설명&quot;하는 대신 &ldquo;보여&quot;줍니다. 준비해 왔는지, 진짜 호기심이 있는지, 상대의 시간을 존중하는지. 어떤 채용 페이지보다 많은 걸 말해주죠. 이건 반대 방향으로도 작동합니다. 긴장이 풀린 대화에서의 모습은 연습된 면접보다 함께 일할 사람에 대해 훨씬 많은 걸 알려줍니다.</p>
<p>특히 효과가 좋은 순간은 이렇습니다. 이직 생각이 없는 사람에게 다가갈 때, 정식 절차 전에 추천받은 사람과 미리 안면을 틀 때, 커리어 전환(IC에서 매니지먼트로, 스타트업에서 대기업으로, 혹은 그 반대)을 고민하는 사람과 이야기할 때. 인재 쟁탈전이 벌어지는 시장에서는 원하는 사람 대부분이 이 셋 중 하나에 해당합니다.</p>

<h4 class="relative group">진행 방식
    <div id="진행-방식" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a7%84%ed%96%89-%eb%b0%a9%ec%8b%9d" aria-label="앵커">#</a>
    </span>
    
</h4>
<p>첫 메시지가 전부를 결정합니다. 템플릿 같은 접근은 그냥 삭제당합니다. 사전 조사를 하고, 의도를 솔직하게 씁니다.</p>
<p><em>&ldquo;안녕하세요 Sarah님, QCon에서 하신 분산 시스템 발표와 이벤트 소싱에 대한 블로그 글을 잘 봤습니다. [회사]에서도 결제 인프라를 확장하면서 비슷한 문제와 씨름하고 있습니다. 30분 커피챗 어떠세요? 면접 의제는 없습니다—그저 관점을 듣고 저희가 하는 일을 공유하고 싶을 뿐입니다.&rdquo;</em></p>
<p>이게 통하는 이유는 구체적이고, 의도를 숨기지 않고, 시간만 달라고 하는 게 아니라 &ldquo;흥미로운 문제에 대한 대화&quot;라는 가치를 내밀기 때문입니다. 그다음은 상대의 수고를 줄여주는 일입니다. 시간 옵션을 몇 개 제시하고, 상대에게 편한 장소(온라인이라면 다운로드가 필요 없는 화상 도구)를 고르고, 내용이 명확한 캘린더 초대를 보내서 아무것도 추측하게 만들지 않는 겁니다.</p>
<p>대화 자체는 느슨한 틀이면 충분합니다. 처음 몇 분은 진짜 스몰토크와 연락한 이유. 다음은 상대의 이야기입니다. 지금 하는 일, 즐거운 것, 답답한 것, 다음에 원하는 것. 여기서 할 일은 말하기보다 듣기입니다. 그다음이 우리 이야기입니다. 미션과 팀이 실제로 안고 있는 과제를, 힘든 부분까지 포함해서요. 후보자는 투명함을 존중하고, 영업 냄새는 귀신같이 맡습니다. 가장 값진 구간은 후반의 열린 시간인데, &ldquo;어떤 조건이 갖춰지면 이직을 고려하시겠어요?&ldquo;를 함께 탐색합니다. 마무리는 다음 단계를 분명히. &ldquo;계속 연락하고 지내요&rdquo; 정도라도 괜찮습니다.</p>
<p>끝나면 24시간 안에 대화 속 구체적인 내용을 언급한 짧은 감사 메시지를 보냅니다. 약속한 건(소개든 링크든) 바로 전달하고요. 이런 심심한 뒷정리야말로 회사 문화를 진짜로 보여주는 대목입니다.</p>
<p>이걸 꾸준히 할 거라면, 대화한 사람들을 간단한 스프레드시트로 관리하고 자리가 없을 때도 가끔 안부를 물어보세요. 매니저 전용 활동으로 둘 필요도 없습니다. 엔지니어들이 자기 네트워크의 멋진 사람들과 커피를 마시는 것. 좋은 리퍼럴은 대개 거기서 시작됩니다.</p>

<h4 class="relative group">써먹을 수 있는 질문들
    <div id="써먹을-수-있는-질문들" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%8d%a8%eb%a8%b9%ec%9d%84-%ec%88%98-%ec%9e%88%eb%8a%94-%ec%a7%88%eb%ac%b8%eb%93%a4" aria-label="앵커">#</a>
    </span>
    
</h4>
<p>제가 자주 묻는 것:</p>
<ul>
<li>&ldquo;최근에 작업한 것 중 제일 흥미로웠던 문제는 뭐였나요?&rdquo;</li>
<li>&ldquo;다음 직장에서는 뭐가 달라졌으면 하나요?&rdquo;</li>
<li>&ldquo;어떤 방식으로 배우는 게 잘 맞나요? 앞으로 어떻게 성장하고 싶으세요?&rdquo;</li>
<li>&ldquo;핏이 맞을지 판단하는 데 도움이 될 만한, 궁금한 게 있으신가요?&rdquo;</li>
</ul>
<p>제가 후보자 쪽이라면 물어볼 것:</p>
<ul>
<li>&ldquo;팀이 지금 마주한 가장 큰 과제는 뭔가요?&rdquo;</li>
<li>&ldquo;이 역할의 성공은 어떻게 측정하나요?&rdquo;</li>
<li>&ldquo;승진 경로는 어떻게 되나요?&rdquo;</li>
<li>&ldquo;왜 이 회사에 오셨어요? 왜 계속 계신가요?&rdquo;</li>
<li>&ldquo;여기서 일하는 것에 대해, 제가 들으면 의외라고 할 만한 게 있나요?&rdquo;</li>
</ul>

<h4 class="relative group">커피챗 제안을 받은 쪽이라면
    <div id="커피챗-제안을-받은-쪽이라면" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%bb%a4%ed%94%bc%ec%b1%97-%ec%a0%9c%ec%95%88%ec%9d%84-%eb%b0%9b%ec%9d%80-%ec%aa%bd%ec%9d%b4%eb%9d%bc%eb%a9%b4" aria-label="앵커">#</a>
    </span>
    
</h4>
<p>커피챗이 무슨 뜻인지 찾아보는 사람은 대부분 저와 테이블 반대편에 앉는 쪽입니다. 누군가에게 커피챗 제안을 받았고, 어떤 자리에 나가게 되는 건지 알고 싶은 거죠. 초대를 보내는 쪽에서 해 드리고 싶은 이야기는 이렇습니다.</p>
<p>면접이 아닙니다. 아무도 점수를 매기지 않고 테스트도 없으니 모범 답안을 준비할 필요는 없습니다. 그래도 첫인상인 건 맞으니, 친구의 친구를 만난다기보다 미래의 동료를 만난다고 생각하세요. 면접과 다른 점은 마음껏 궁금해해도 된다는 것, 그리고 대답하는 만큼 질문도 하길 기대받는다는 것입니다.</p>
<p>복장은 그 회사에 평범한 날 출근할 때 입을 법한 옷이면 됩니다. 잘 모르겠으면 깔끔한 캐주얼이 틀릴 일은 없습니다. 화상 통화라면 카메라를 켜고 조용한 방을 찾으세요. 셔츠보다 그게 더 중요합니다.</p>
<p>준비는 30분 정도면 충분합니다. 그 회사가 뭘 만드는지, 상대가 쓴 글이나 만든 게 있다면 읽어 보세요. 지금 하는 일과 다음에 하고 싶은 일을 2분 안에 말할 수 있게 정리해 두세요. 그 질문은 반드시 나오니까요. 직접 물어볼 질문도 두세 개 챙겨 가세요. 위의 질문 리스트로 시작해도 괜찮습니다.</p>
<p>무슨 이야기를 할지는 이렇습니다. 내 일, 그 일에서 즐거운 부분, 상대의 일에서 궁금한 부분. 연봉 이야기는 상대가 먼저 꺼내지 않는 한 나중으로 미루세요. 염두에 둔 포지션이 있는지, 있다면 절차가 어떻게 되는지 묻는 건 전혀 문제없습니다.</p>
<p>계산은 보통 초대한 쪽이 합니다. 내겠다고 말은 하되, 계산대 앞에서 실랑이까지 할 필요는 없습니다. 하루 안에 실제로 나눈 이야기를 하나 언급한 짧은 감사 메시지를 보내면, 이미 대부분의 사람보다 잘한 겁니다.</p>
<p>그리고 만나 보고 싶은 사람이 있다면 직접 커피챗을 요청하세요. 메시지는 짧게, 왜 하필 그 사람인지 밝히고, 수락하기 쉽게 만드는 게 요령입니다. &ldquo;팀에서 진행하신 새 검색 기능 작업을 계속 지켜보고 있었습니다. 저도 플랫폼 엔지니어링 쪽으로 옮기는 걸 고민하고 있는데, 몇 주 안에 30분 정도 커피나 통화 가능하실까요? 시간은 편하신 대로 맞추겠습니다.&rdquo; 이 정도로 구체적인 요청이면 대부분 응해 줍니다.</p>

<h4 class="relative group">망치는 방법들
    <div id="망치는-방법들" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a7%9d%ec%b9%98%eb%8a%94-%eb%b0%a9%eb%b2%95%eb%93%a4" aria-label="앵커">#</a>
    </span>
    
</h4>
<p>제일 빠른 건 몰래 면접으로 바꾸는 겁니다. 기술 역량을 테스트하거나 행동 면접 질문을 슬쩍 끼워 넣는 순간 암묵적인 약속은 깨집니다. 그건 정식 프로세스를 위해 아껴두세요. 그다음이 과한 영업입니다. 오래 남는 채용은 힘든 부분까지 다 보고 들어온 사람들에게서 나옵니다. 준비 없이 나타나는 것, 끝나고 연락이 끊기는 것도 조용히 타격을 줍니다. 커피챗 한 번의 인상이, 그 사람이 자기 네트워크에 여러분 회사를 어떻게 이야기할지를 정하니까요.</p>
<p>제 쪽에서 보는 위험 신호는 이렇습니다. 아무것에도 호기심이 없는 후보자, 완전히 거래처럼 느껴지는 대화, 과거 직장을 전부 똑같은 원망조로 이야기하는 사람. 후보자도 자기만의 리스트를 갖고 있어야 합니다. 일의 의미를 설명하지 못하는 담당자, 이직률이나 회사 방향에 대한 얼버무림, 여러분을 이해하기보다 팔아넘기는 데 열심인 상대.</p>
<p>모든 커피챗이 어딘가로 이어지는 건 아닙니다. 사실 대부분은 안 이어져요. 그래도 괜찮습니다. 중요한 건, 다음에 핵심 포지션을 채워야 할 때 백지 채용 공고가 아니라 쌓여 있는 진짜 대화들에서 시작할 수 있다는 점입니다. 직무 기술서 말고, 커피 한잔하자는 초대를 보내세요.</p>

<h4 class="relative group">추가 읽기
    <div id="추가-읽기" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%b6%94%ea%b0%80-%ec%9d%bd%ea%b8%b0" aria-label="앵커">#</a>
    </span>
    
</h4>
<p><strong>이 사이트의 관련 글:</strong></p>
<ul>
<li><a href="https://jared.lynskey.co.nz/ko/posts/2024/2024-12-19-star-interviews/" >개발자 면접에서 STAR 방식을 쓰는 이유</a> - 커피챗이 정식 면접 프로세스로 이어졌을 때를 위해</li>
<li><a href="https://jared.lynskey.co.nz/ko/posts/2024/2024-02-10-prioritizing-onboarding/" >새로 엔지니어링 매니저가 되면서 집중하기로 한 세 가지</a> - 팀을 굴러가게 하는 것이 무엇인지. 결국 매칭에서 봐야 할 것들입니다</li>
<li><a href="https://jared.lynskey.co.nz/ko/posts/2024/2024-07-01-internships/" >스타트업에서 인턴을 해야 하는 이유</a> - 스타트업행을 고민하는 사람과 이야기할 때의 배경 지식으로</li>
</ul>
<p><strong>외부 리소스:</strong></p>
<ul>
<li><a href="https://review.firstround.com/articles/hiring-engineers/"  target="_blank" rel="noreferrer">First Round Review: 엔지니어 채용</a> - 경험 많은 운영자들이 쓴 스타트업 채용 가이드</li>
<li><a href="https://larahogan.me/blog/first-one-on-one-questions/"  target="_blank" rel="noreferrer">Lara Hogan의 &ldquo;첫 1:1을 위한 질문&rdquo;</a> - 1:1용으로 쓰였지만 커피챗에서도 그대로 잘 먹힙니다</li>
<li><a href="https://www.kalzumeus.com/2012/01/23/salary-negotiation/"  target="_blank" rel="noreferrer">Patrick McKenzie의 연봉 협상 글</a> - 후보자 쪽 시각을 이해하는 데 좋습니다</li>
<li><a href="https://whothebook.com/" target="_blank" rel="noreferrer">Who: 채용의 A 메소드</a> - Geoff Smart와 Randy Street의 체계적인 채용 프레임워크</li>
<li><a href="https://hbr.org/topic/subject/hiring-and-recruitment"  target="_blank" rel="noreferrer">Harvard Business Review: 채용</a> - 인재 확보에 대한 연구 기반 글 모음</li>
</ul>
]]></content:encoded>
      <media:content url="https://jared.lynskey.co.nz/en/posts/2024/2024-07-12-coffee-chats/featured.jpg" medium="image" type="image/jpeg" />
    </item>
    <item>
      <title>키위 챔버 리더십 조찬 강연: 치매 케어 로봇과 뉴질랜드 혁신 이야기</title>
      <link>https://jared.lynskey.co.nz/ko/posts/2018/2018-11-12-kiwichamberbreakfast/</link>
      <guid isPermaLink="true">https://jared.lynskey.co.nz/ko/posts/2018/2018-11-12-kiwichamberbreakfast/</guid>
      <pubDate>Mon, 12 Nov 2018 00:00:00 +0000</pubDate>
      <dc:creator>Jared Lynskey</dc:creator>
      <category>Kiwi Chamber</category>
      <category>Networking</category>
      <category>New Zealand</category>
      <category>Korea</category>
      <category>Photography</category>
      <description>2018년 마지막 키위 챔버 조찬 행사에서 찍은 사진과 강연 메모입니다. 이화여대 김건하 교수의 치매 케어 로봇, 오클랜드 대학교 유니서비스 소개, 뉴질랜드 혁신 이야기를 담았습니다.</description>
      <content:encoded><![CDATA[<p>주한 뉴질랜드 상공회의소인 키위 챔버는 올해 조찬 행사를 여러 번 열었는데, 오늘이 그 마지막이었습니다. 저는 자원봉사 사진 촬영을 맡았습니다. 연사로는 오클랜드 대학교의 <a href="https://profiles.auckland.ac.nz/p-medrano"  target="_blank" rel="noreferrer">파우 메드라노-그라시아 박사</a>와 이화여자대학교 김건하 교수가 초청됐습니다.</p>

<h2 class="relative group">치매 케어 로봇
    <div id="치매-케어-로봇" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%b9%98%eb%a7%a4-%ec%bc%80%ec%96%b4-%eb%a1%9c%eb%b4%87" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>신경과 전문가인 김 교수의 강연 주제는 &ldquo;치매 케어 로봇&quot;이었습니다. 집에서 치매 환자의 일상을 돕는 케어 로봇의 생활 지원 기능을 설명해 주셨고, 인식 능력을 꾸준한 학습으로 키워가는 로봇과 이를 활용한 인지 훈련 프로그램 이야기도 들려주셨습니다. 산업통상자원부 지원을 받아 가정에서 치매 환자를 돌보는 로봇을 공동 개발 중이라고 하는데요. 이 프로젝트의 로봇은 2019년에 효과성 평가를 거치고, 잘 마무리되면 실제 운영으로 이어져 가정용 치매 케어 로봇 개발로 연결될 예정이라고 합니다.</p>
<p><figure><span class="mc-img" style="--lqip:url('data:image/webp;base64,UklGRgoBAABXRUJQVlA4IP4AAACwBgCdASogABUAPw1sqEemIyIYBABjEMTygFnC1fKObUlMuCPffRx2qjMs6hwud2hZAKC2pEZcn/Ek30n6QAD+vGgF9ixxyGqUIN5Da06wGtaJixU9JVctynhbD2aLNaCbuHrKh0BV7zApQFTbO4ZZmkPFJQFSb9Hgmu+87waDlsynCsEAIB/1BOQrNbdJqccZ7gPnD0DUmCrKfycyXXK4FEr5PzBOfD/UPnyW4K4nCdw7pzLdChH9/8/7zIf3G422csvM3ot5yTedsh/4iSGI1FbjWI2V+/gEtoEFwnXYCjf6U+V5PD4ey+CMHj+dYwG2bGdrmJ3hVWWTrnAAAA==')"><img
    class="my-0 rounded-md"
    loading="lazy"
    decoding="async"
    fetchpriority="auto"
    alt="치매 케어 로봇"
    width="500"
    height="333"
    src="https://jared.lynskey.co.nz/img/posts/kiwicham/robots_hu_fddd1ab2bf1e39b2.webp"
    srcset="https://jared.lynskey.co.nz/img/posts/kiwicham/robots_hu_fddd1ab2bf1e39b2.webp 800w, https://jared.lynskey.co.nz/img/posts/kiwicham/robots_hu_fddd1ab2bf1e39b2.webp 1280w"
    sizes="(min-width: 768px) 50vw, 65vw"
    data-zoom-src="https://jared.lynskey.co.nz/img/posts/kiwicham/robots_hu_fddd1ab2bf1e39b2.webp"></span></figure>
</p>

<h2 class="relative group">유니서비스
    <div id="유니서비스" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9c%a0%eb%8b%88%ec%84%9c%eb%b9%84%ec%8a%a4" aria-label="앵커">#</a>
    </span>
    
</h2>
<p>메드라노-그라시아 박사는 유니서비스에서 비즈니스 개발 매니저로 어떤 일을 하는지 소개했습니다. 오클랜드 대학교의 뛰어난 인재들과 손잡고, 세상을 바꿀 만한 아이디어를 현실로 만들어가는 조직입니다.</p>

<h2 class="relative group">업스타터스
    <div id="업스타터스" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%97%85%ec%8a%a4%ed%83%80%ed%84%b0%ec%8a%a4" aria-label="앵커">#</a>
    </span>
    
</h2>

<h3 class="relative group">새로운 땅에서 나오는 새로운 아이디어
    <div id="새로운-땅에서-나오는-새로운-아이디어" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%83%88%eb%a1%9c%ec%9a%b4-%eb%95%85%ec%97%90%ec%84%9c-%eb%82%98%ec%98%a4%eb%8a%94-%ec%83%88%eb%a1%9c%ec%9a%b4-%ec%95%84%ec%9d%b4%eb%94%94%ec%96%b4" aria-label="앵커">#</a>
    </span>
    
</h3>
<p>필요는 발명의 어머니라고 하죠. 그렇다면 세상을 바꾸는 아이디어가 뉴질랜드에서 나오는 것도 이상한 일은 아닙니다. 뉴질랜드의 테크와 혁신 이야기가 소개됐습니다.</p>
<p>화면에 소개된 사례 중 하나는 Dotterel의 경량 드론 슈라우드였습니다. Revolution Fibres의 흡음 나노섬유를 써서 드론 소음을 속삭임 수준으로 줄인다는 내용이었죠.</p>
<p><figure><span class="mc-img" style="--lqip:url('data:image/webp;base64,UklGRugAAABXRUJQVlA4INwAAADwBACdASogABAAPw1oqUgmIyIYBABjEMTzAE6CcSqxGbIEX7otGpjvWjbrOy0y3AAA/v8P95FBHbx/eVAFd87YDN20UkKrX+X+oRfja0b8aq3z9HfBPSUhf0mHywaw8ipKFTXXfNIqL+ySVpTrKz6x12jS1Df/q8u1uQnOTGd/Nd3Tzk+SzxOpirnxcjzyPZ1mz3/OU1efwtzVn8CmK2ehuRsYFBVudResoch6qtj5y7F/Y0jyolyhJBYJMPZEbvZwvvQ0luZEzRMNgtFHUtsJ1E9hx+2CRju11UAA')"><img
    class="my-0 rounded-md"
    loading="lazy"
    decoding="async"
    fetchpriority="auto"
    alt="Upstarters 슬라이드: Dotterel과 Revolution Fibres의 저소음 드론"
    width="3333"
    height="1667"
    src="https://jared.lynskey.co.nz/img/posts/kiwicham/dottereal_hu_9b87e875ec570375.webp"
    srcset="https://jared.lynskey.co.nz/img/posts/kiwicham/dottereal_hu_9b87e875ec570375.webp 800w, https://jared.lynskey.co.nz/img/posts/kiwicham/dottereal_hu_4d2cd746e5192f61.webp 1280w"
    sizes="(min-width: 768px) 50vw, 65vw"
    data-zoom-src="https://jared.lynskey.co.nz/img/posts/kiwicham/dottereal_hu_884acb3c86c8a21b.webp"></span></figure>
</p>

<h2 class="relative group">행사에서 찍은 사진
    <div id="행사에서-찍은-사진" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%96%89%ec%82%ac%ec%97%90%ec%84%9c-%ec%b0%8d%ec%9d%80-%ec%82%ac%ec%a7%84" aria-label="앵커">#</a>
    </span>
    
</h2>
<script src="https://cdn.jsdelivr.net/npm/publicalbum@latest/dist/pa-embed-player.min.js" async></script>
<div class="pa-embed-player" style="width:100%; height:480px; display:none;"
  data-link="https://photos.app.goo.gl/ZNVotgWiE8N75wpe9"
  data-title="Kiwi Chamber New Zealand Leadership Speaker Series"
  data-description="41 new photos · Album by Jared Lynskey (인재덕)">
  <img data-src="https://lh3.googleusercontent.com/S_fiPGQ-7UMgrKajgQea8ArfZaVFKheFriodbSol_G-pStF7yAXvBueXxKXd3WLz3xS44fCB6iAPw-3fx6ek9ibPOcgcHjFROsH2C821GpAdfY-k-ewtgxxFvMG1faI9ZAOd0D0pDKY=w1920-h1080" src="" alt="" />
</div>
<p>이렇게 두 나라의 관계를 다지는 행사에서 자원봉사하는 건 언제나 즐겁습니다.</p>
<p>어두운 행사장에서는 밝은 렌즈가 필수입니다. 부족한 빛을 큰 플래시로 채우려 들면 청중과 연사에게 얼마나 방해가 되겠어요. 보기에도 영 좋지 않고요.</p>
]]></content:encoded>
      <media:content url="https://jared.lynskey.co.nz/en/posts/2018/2018-11-12-kiwichamberbreakfast/featured.jpg" medium="image" type="image/jpeg" />
    </item>
  </channel>
</rss>
