안녕하세요. 서비스기획자 용진입니다. 돈 아끼려고 n8n 셀프호스팅 했다가 홈 서버 만든 이야기 (1)에서 이어지는 내용이니 이전 내용도 한번 읽어봐주시면 좋겠네요.

왜 나는 SSL/TLS 인증을 받지 못했는가

결국 저는 SSL/TLS 인증서보안을 강화하기 위한 인증서라고 생각하시면 됩니다. 를 적용하는데 실패하였습니다. 정확히는 와일드카드 인증서를 받는데 실패하였습니다. 이 부분때문에 거의 때려치려고 생각했죠. 이후에 홈 서버를 거의 완성하고 제가 왜 실패했는지 이것저것 찾아보다 가장 유력한 원인으로 꼽을만한 것을 하나 찾았습니다.

저는 홈 서버용 미니PC 외에 시놀로지 NASNetwork Attached Storage, 네트워크 결합 스토리지를 하나 가지고 있습니다. 오래 저장해야하는 데이터를 저장하는 용도로 사용하고 있죠. 그리고 시놀로지 NAS는 외부 연결을 위해 DDNSDynamic Domain Name System, 동적 DNS 와 SSL 인증서를 자체적으로 제공하죠. 한 IP 주소 안에서 DDNS 포트포워딩과 SSL 인증서 발급을 여러 번 수행하기 어렵기 때문에 일반적으로 NPM 사용 시 NAS의 DDNS와 SSL 기능을 꺼버리라고 하네요. 아마 이것때문에 계속 안되지 않을까 생각합니다. 물론 저는 전문가가 아니기 때문에 추정만 하고 있지요.

거의 때려치려는 저는 인터넷 서칭 중에 "traefik 서비스와 cloudflare tunnel을 가지고 홈 서버를 구현"한 블로그를 보게 되었습니다. 그리고 당장 cloudflare의 tunnel을 찾아보았죠.

Cloudflare Tunnel을 알게 되다

Zero-Trust?

클라우드플레어의 터널 서비스는 제로 트러스트 제품군에 있는 서비스입니다. 제로 트러스트가 무엇인지 자세히 알 필요는 없지만 대략적으로 무엇인지 알면 서비스기획자로서도 도움이 되겠죠. 제로 트러스트란 '아무것도 믿지 않음'으로서 보안을 지키는 방식입니다.

제로 트러스트를 설명하는 일러스트
내부도 믿지 않음으로서 내부 사용자는 '많이' 귀찮겠지만 그만큼 보안은 유지됩니다. 보안과 편의는 상충관계죠.

일반적으로, 기업에서는 외부의 공격에는 엄격하게 대응하지만 내부에서의 움직임은 신경쓰지 않는 경우가 많습니다. '신뢰하는 내부'와 '신뢰하지 않는 외부'가 나뉘는 것이죠. 집으로 비유해보면 이렇습니다. 우리는 공동 현관에 비밀번호 패드를 달아놓고, 우리집 현관문에도 도어락을 달아놓죠. 하지만 집 안 방문마다 도어락은 달아놓지 않습니다. 즉 '외부는 믿지 않지만 내부는 마음껏 돌아다니는 상황' 인거죠.

이런 상황에서 외부에서 내부로 들어올 수만 있다면 내부에서는 마음껏 휘저을 수 있겠죠? 최근 SKT가 바로 이런 꼴이죠 그렇기 때문에 내부 방문에도 모두 도어락을 달아버리는 것이 바로 "제로 트러스트"인 것입니다. 절대 신뢰하지 않음으로서 보안을 유지한다는 것이죠.

Tunnel

클라우드플레어의 제로 트러스트 서비스도 저러한 제로 트러스트에 기반하고 있죠. 사용자의 디바이스에서 들어오는 모든 정보를 본인들이 걸러서 확인하고 자체적인 통로를 통해 내부로 접속, 접속해서도 마음대로 다닐 수 없도록 필요한 부분에만 접속시키는 것이 제로 트러스트 서비스입니다.

클라우드플레어의 제로 트러스트를 표현하는 일러스트
사용자와 리스소 사이에서 클라우드플레어가 서로를 연결해주고 있습니다. 이게 클라우드플레어가 잘되는 이유

이 중 내부로 들어오는 자체적인 통로가 제가 사용하려는 tunnel이라는 서비스입니다. 말 그대로 딱 그것만 뚫고 다른 것들은 막아버리는 것이죠. 그렇기 때문에 터널을 사용할 때 저는 저의 내부 IP를 공개할 필요도 없고, 포트포워딩을 해야할 필요도 사라집니다. 다 클라우드플레어에서 알아서 해버리거든요.

그리고 이 방법의 또 하나의 장점은 SSL/TLS 인증서를 제가 발급받을 필요가 없다는 점입니다. 클라우드플레어까지는 보안 통로로 내용을 오갈 수 있기 때문에 인증서 없이 그냥 정보를 전달하면(Http) 되고 클라우드플레어에서 그 정보를 받아 제 도메인에 연결해준 뒤에 자체 인증서를 제 도메인에 발라버려서 외부로 뿌려버리면(https) 되거든요. 와일드카드 인증서이기 때문에 서브도메인으로 얼마든지 붙일 수 있다는 것 또한 장점입니다. 그렇기 때문에 저는 traefik에서 SSL/TLS 인증서 부분을 아예 주석처리해버렸습니다. 어차피 cloudflare로만 잘 흐르면 문제없기 때문에 443을 닫아버리고 80만 연거죠.

그리고 50명 이하, 저 혼자 사용할 때는 제한적이지만 무료로 사용할 수 있다는 것도 장점입니다. 저는 클라우드플레어에서 도메인만 잘 유지하면 계속 무료로 사용할 수 있는 것이죠.

클라우드플레어 사용 전(위)와 사용 후(아래)
클라우드플레어 사용 전(위)와 사용 후(아래)

tunnel를 사용하니 깔끔해졌다

이렇게 장점이 많은 터널을 사용하려면 우선 클라우드플레어에 등록해야합니다. 클라우드플레어에서 제로트러스트로 들어가 네트워크에서 터널을 선택한 뒤 터널을 만들어줍니다. 터널 이름을 만들고나면 터널의 커넥터를 연결해줘야합니다.

클라우드플레어 터널 설정 화면
클라우드플레어 터널 설정 화면

보통은 저 화면에서 Docker를 선택한 뒤에 나오는 커넥터를 복사/붙여넣기 하지만 저는 traefik을 사용하기 때문에 같이 묶어서 Docker compose로 사용하는 방법을 사용했습니다.

# Traefik 구성은 생략

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=${TOKEN}
    networks:
      - traefik_network

정상적으로 표시되는 N8N
정상적으로 표시되는 N8N

그리고 최종적으로 저는 n8n을 무사히 띄우는데 성공했습니다. 그것도 로컬에서 동작하는 것이 아닌 도메인과 SSL/TLS 인증서를 챙겨 미니 PC만 정상적으로 켜 있다면 24시간 자동화도 충분히 가능하게 말이죠.

(되는 이유는 모르지만) 어쨌든 잘 굴러갑니다

홈 서버의 네트워크에 대한 도식화
홈 서버의 네트워크에 대한 도식화를 하면 이렇습니다.

최종적으로 홈 서버는 다음과 같이 굴러갑니다. 외부에서 접속할 경우 클라우드플레어를 통해 제 내부 네트워크로 들어옵니다. 내부로 들어온 뒤 traefik을 통해 실제 서비스 컨테이너로 접속하게 되죠. 그리고 cloudflared, traefik, 서비스 모두 traefik_network라는 docker의 브릿지를 통해 서로 통신합니다.

되는 원리는 상세하게 모르지만, 어쨌든 제가 할 수 있는 범위 내에서 이렇게 구축을 완료하였고 잘 돌아가고 있습니다. 그럼 된거죠. 예전에는 기술에 대해서 무언가 상세하게 보려고 했다가 지치곤 했었는데, 오히려 내가 쓸 수 있는 범위 내에서만 써보고 문제 없으면 넘기는 게 훨씬 저에게 도움이 된다라는 걸 깨달았습니다.

긴 글 읽어주셔서 감사합니다. 다음에는 N8N 이외에 서비스를 어떻게 붙이는가도 공유해볼까 합니다.