Tailscale 설치 및 설정 (ubuntu + windows + DNS + Https)

ILOV-IT·2025년 5월 29일
post-thumbnail

구글 출신 개발자들이 설립한 Tailscale은 WireGuard 프로토콜을 기반으로 한 VPN 서비스이다. 사용자의 기기 간에 피어 투 피어(P2P) 또는 릴레이 중계 방식으로 VPN 터널을 구성하여 안전한 통신을 제공한다.

  1. NAT 우회(NAT Traversal) 기술인 STUN을 이용해 먼저 직접 연결

  2. 필요 시 UPnP IGD, NAT-PMP, PCP 등의 프로토콜을 통해 자동으로 포트를 포워딩

  3. 만약 피어 간 직접 연결이 불가능할 경우, Tailscale은 자체 DERP(Designated Encrypted Relay for Packets) 서버를 이용해 암호화된 릴레이 통신

Tailscale은 각 클라이언트에게 Carrier-Grade NAT(CGNAT)용으로 예약된 사설 IPv4 주소를 할당한다. 이는 기존 로컬 네트워크와의 IP 충돌을 피하기 위함이다.

또한 Linux 클라이언트는 SNAT(Source NAT)를 비활성화하고, 원본 IP를 그대로 유지한 채로 트래픽을 라우팅할 수 있다. 이를 통해 해당 리눅스 장비가 내부 네트워크 게이트웨이처럼 작동하며, 로컬 네트워크 뒤의 다른 장치로도 VPN을 통해 접속할 수 있다.

1. 회원가입 https://tailscale.com

Tailscale 웹사이트에서 회원가입을 완료하면, 마지막 단계에서 다음과 같은 화면이 나타난다. 이 화면에는 curl 명령어가 제공되는데, 이 명령어를 서버에서 실행하면 Tailscale을 간편하게 설치할 수 있다.

2. 서버에 설치 및 실행

설치가 완료되면 sudo tailscale up 명령어를 입력해 Tailscale 서비스를 시작한다. 명령어를 실행하면 브라우저 로그인용 URL이 출력되며, 해당 URL에 접속해 로그인하면 서버가 Tailscale 네트워크에 연결된다. 이 메시지의 마지막 부분에 임시 로그인 URL이 표시되며, 이를 통해 인증 과정을 진행할 수 있다.

$ curl -fsSL https://tailscale.com/install.sh | sh
 # Installing Tailscale for ubuntu jammy, using method apt
 # + sudo mkdir -p --mode=0755 /usr/share/keyrings
 # [sudo] password for ----:

$ sudo tailscale up 
 # [sudo] password for ----:
 # To authnenticate, visit:
 # https://login.tailscale.com/a/?????????????????
 #

3. 서버 설치 후 나오는 URL를 방문

해당 URL을 브라우저에서 열면 Tailscale 로그인 페이지가 나타나고, 로그인 후 Connect 버튼이 보인다. Connect를 클릭하면, 해당 서버가 Tailscale 네트워크에 등록되며 연결된 디바이스 목록에 나타나게 된다.

4. 클라이언트에 설치 https://tailscale.com/download

Windows 버전의 Tailscale을 설치한 후, 가입했던 이메일 주소로 로그인하면 자동으로 서버와 연결된다. 별도의 설정 없이도 네트워크에 참여하게 되며, 로그인과 동시에 장치가 Tailscale 네트워크에 등록된다.

Tailscale 웹 대시보드에 접속하면, 현재 연결된 기기 목록을 확인할 수 있다. 각 기기별로 할당된 IP 주소, 기기 이름, 최근 접속 시각 등의 정보도 함께 제공된다.

Tailscale 대시보드에서 My Devices를 클릭하면, 연결된 서버와 클라이언트 목록을 확인할 수 있다. 각 장치 옆에는 100.xxx.xxx.xxx 형식의 IP 주소가 표시되는데, 이는 Tailscale이 자동으로 할당한 가상 네트워크 주소다.

이 주소는 실제 사설망처럼 작동하며, SSH 접속, 데이터베이스 연결, 원격 제어 등 다양한 네트워크 작업에 사용할 수 있다. Tailscale 네트워크 내의 다른 장치에서도 이 주소를 통해 해당 서버에 직접 접근할 수 있다.

5. 다른 사용자들 초대

6. DNS + Https 적용

가장 맘에 드는 기능이다. 제로트러스트 메쉬 네트워크 상에서 자동 TLS(ACME 기반) 를 제공하여, 내부 IP만 가진 서비스도 공개 인증서 기반 HTTPS를 사용할 수 있게 한다.

your-server$
your-server$
your-server$ sudo tailscale cert yourserver.xxxxxxx.ts.net
# Wrote public cert to yourserver.xxxxxxx.ts.net.crt
# Wrote private key to yourserver.xxxxxxx.ts.net.key

your-server$
your-server$
your-server$ sudo mkdir -p /etc/ssl/certs /etc/ssl/private

your-server$
your-server$
your-server$ sudo mv yourserver.xxxxxxx.ts.net.crt /etc/ssl/certs/
your-server$ sudo mv yourserver.xxxxxxx.ts.net.key /etc/ssl/private/


your-server$
your-server$
your-server$ sudo chmod 644 /etc/ssl/certs/yourserver.xxxxxxx.ts.net.crt
your-server$ sudo chmod 600 /etc/ssl/private/yourserver.xxxxxxx.ts.net.key

your-server$
your-server$
your-server$ sudo vim /etc/nginx/conf.d/mapandnote-web.conf
# server {
#     listen 443 ssl;
#     server_name yourserver.xxxxxxx.ts.net;

#     ssl_certificate     /etc/ssl/certs/yourserver.xxxxxxx.ts.net.crt;
#     ssl_certificate_key /etc/ssl/private/yourserver.xxxxxxx.ts.net.key;

#     location / {
#         proxy_pass 여기는 기존 서버와 연결하는 방식(socket 등등)
#         proxy_set_header Host $host;
#         proxy_set_header X-Real-IP $remote_addr;
#         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#         proxy_set_header X-Forwarded-Proto $scheme;
#     }
#     add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data:; font-src 'self' data: https://cdn.jsdelivr.net; connect-src 'self'; frame-ancestors 'self'; base-uri 'self';" always;
# }

your-server$
your-server$
your-server$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

your-server$
your-server$
your-server$ sudo systemctl reload nginx
your-server$ sudo systemctl restart nginx

your-server$
your-server$
your-server$
your-server$ sudo vim /etc/systemd/system/tailscale-cert-renew.service
# [Unit]
# Description=Renew Tailscale TLS certificate
# After=network-online.target
# Wants=network-online.target

# [Service]
# Type=oneshot
# ExecStart=/usr/bin/tailscale cert \
#   --cert-file /etc/ssl/certs/yourserver.xxxxxxx.ts.net.crt \
#   --key-file /etc/ssl/private/yourserver.xxxxxxx.ts.net.key \
#   yourserver.xxxxxxx.ts.net

# # 인증서가 갱신된 뒤 Nginx reload
# ExecStartPost=/bin/systemctl reload nginx


your-server$
your-server$
your-server$
your-server$ sudo vim /etc/systemd/system/tailscale-cert-renew.timer
# [Unit]
# Description=Run Tailscale TLS cert renew daily

# [Timer]
# OnCalendar=daily
# Persistent=true

# [Install]
# WantedBy=timers.target

your-server$
your-server$
your-server$
your-server$ sudo systemctl daemon-reexec
your-server$ sudo systemctl enable --now tailscale-cert-renew.timer


your-server$
your-server$
your-server$ systemctl list-timers tailscale-cert-renew.timer
your-server$ journalctl -u tailscale-cert-renew.service

add_header Content-Security-Policy를 한 줄로 작성하지 않을 경우, next.js에서 향후 에러가 발생한다.

The only way to fix this is for the developer of the API at ooooo.xxxxx.ts.net to correct the malformed Content-Security-Policy header. The server must send that header's value as a single, continuous line. Until they fix their server's response, your Next.js application will be unable to correctly process a successful response from that endpoint.

profile
because we know you'll love it

0개의 댓글