# LXC Caddy에서 호스트 Tailscale 네트워크 연결 가이드 ## 📅 작성일 2025년 9월 22일 ## 🎯 개요 호스트에 Tailscale이 설치된 환경에서 LXC 컨테이너의 Caddy가 Tailscale 네트워크에 접근할 수 있도록 설정하는 완전한 가이드입니다. ## 🏗️ 시스템 구성 ### 환경 정보 - **호스트**: Proxmox VE (Tailscale 설치됨) - **LXC 컨테이너**: Caddy 웹서버 (ID: 103) - **목표**: LXC Caddy에서 Tailscale 네트워크의 서버들에 리버스 프록시 ### 네트워크 구조 ``` 인터넷 → 도메인(*.pharmq.kr) → Caddy(LXC 103) → 호스트(라우팅) → Tailscale 네트워크 ``` ## ✅ 전제 조건 ### 1. 호스트 Tailscale 설치 확인 ```bash # 호스트에서 Tailscale 상태 확인 tailscale status # 출력 예시: # 100.64.0.3 pve-p2 myuser linux - # 100.64.0.6 pve-hp myuser linux - # 100.64.0.11 pve-p1 myuser linux - ``` ### 2. LXC 컨테이너 정보 확인 ```bash # LXC 네트워크 정보 확인 pct exec 103 -- ip addr show eth0 # 출력 예시: # inet 192.168.0.19/24 brd 192.168.0.255 scope global dynamic eth0 ``` ## 🔧 설정 단계 ### 1단계: 호스트에서 IP 포워딩 활성화 ```bash # IP 포워딩 활성화 (임시) echo 1 > /proc/sys/net/ipv4/ip_forward # IP 포워딩 영구 활성화 echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf sysctl -p ``` **확인:** ```bash cat /proc/sys/net/ipv4/ip_forward # 출력: 1 ``` ### 2단계: LXC에서 Tailscale 네트워크로 라우팅 추가 ```bash # LXC에 라우팅 규칙 추가 (임시) pct exec 103 -- ip route add 100.64.0.0/10 via 192.168.0.200 # 라우팅 확인 pct exec 103 -- ip route | grep 100.64 # 출력: 100.64.0.0/10 via 192.168.0.200 dev eth0 ``` **영구 라우팅 설정:** ```bash # LXC 내부에서 설정 pct exec 103 -- bash -c 'echo "100.64.0.0/10 via 192.168.0.200" >> /etc/systemd/network/10-eth0.network' # 또는 /etc/network/interfaces 사용 (Debian 기반) pct exec 103 -- bash -c 'echo "up ip route add 100.64.0.0/10 via 192.168.0.200" >> /etc/network/interfaces' ``` ### 3단계: iptables MASQUERADE 설정 (핵심!) **⚠️ 중요: 이 단계가 없으면 일부 Tailscale 노드 연결이 실패할 수 있습니다.** ```bash # LXC에서 Tailscale 네트워크로의 트래픽에 MASQUERADE 적용 iptables -t nat -A POSTROUTING -s 192.168.0.19 -d 100.64.0.0/10 -j MASQUERADE # MASQUERADE 규칙 확인 iptables -t nat -L POSTROUTING -v -n | grep 100.64 ``` **영구 iptables 설정:** ```bash # iptables-persistent 설치 (Debian/Ubuntu) apt-get install iptables-persistent # 현재 규칙 저장 iptables-save > /etc/iptables/rules.v4 # 또는 systemd 서비스로 영구화 cat > /etc/systemd/system/lxc-tailscale-nat.service << 'EOF' [Unit] Description=LXC Tailscale NAT Rules After=network.target [Service] Type=oneshot ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 192.168.0.19 -d 100.64.0.0/10 -j MASQUERADE RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF systemctl enable lxc-tailscale-nat.service ``` ### 4단계: 연결 테스트 ```bash # LXC에서 Tailscale 네트워크 ping 테스트 pct exec 103 -- ping -c 2 100.64.0.3 # 출력 예시: # PING 100.64.0.3 (100.64.0.3) 56(84) bytes of data. # 64 bytes from 100.64.0.3: icmp_seq=1 ttl=64 time=0.038 ms # 64 bytes from 100.64.0.3: icmp_seq=2 ttl=64 time=0.047 ms ``` ### 5단계: Caddyfile 설정 **호스트 기준 Tailscale IP 매핑 확인:** ```bash # 호스트에서 Tailscale 노드 목록 확인 tailscale status # 예시 출력: # 100.64.0.3 pve-p2 myuser linux - # 100.64.0.6 pve-hp myuser linux - # 100.64.0.11 pve-p1 myuser linux - # 100.64.0.12 pve7 myuser linux - ``` **Caddyfile 설정 예시:** ```caddyfile { email admin@pharmq.kr acme_dns cloudflare YOUR_CLOUDFLARE_TOKEN } # 와일드카드 인증서 *.pharmq.kr { tls { dns cloudflare YOUR_CLOUDFLARE_TOKEN } respond "Wildcard domain: {host} - SSL ready!" 200 } # PVE 노드들 (호스트 기준 Tailscale 네트워크) p2.pharmq.kr { reverse_proxy https://100.64.0.3:8006 { transport http { tls_insecure_skip_verify } } tls { dns cloudflare YOUR_CLOUDFLARE_TOKEN } } hp.pharmq.kr { reverse_proxy https://100.64.0.6:8006 { transport http { tls_insecure_skip_verify } } tls { dns cloudflare YOUR_CLOUDFLARE_TOKEN } } p1.pharmq.kr { reverse_proxy https://100.64.0.11:8006 { transport http { tls_insecure_skip_verify } } tls { dns cloudflare YOUR_CLOUDFLARE_TOKEN } } ``` ### 6단계: Caddy 설정 적용 ```bash # Caddyfile 문법 검증 pct exec 103 -- caddy validate --config /etc/caddy/Caddyfile # Caddy 설정 다시 로드 pct exec 103 -- systemctl reload caddy # Caddy 상태 확인 pct exec 103 -- systemctl status caddy ``` ### 7단계: 최종 테스트 ```bash # 외부에서 도메인 접근 테스트 curl -I https://p2.pharmq.kr # 성공 예시 응답: # HTTP/2 501 # server: pve-api-daemon/3.0 # via: 1.1 Caddy ``` ## 🔍 문제 해결 ### 문제 1: LXC에서 Tailscale IP 접근 불가 **증상:** ```bash pct exec 103 -- ping 100.64.0.3 # PING 100.64.0.3 (100.64.0.3) 56(84) bytes of data. # --- 100.64.0.3 ping statistics --- # 2 packets transmitted, 0 received, 100% packet loss ``` **해결책:** ```bash # 1. 호스트 IP 포워딩 확인 cat /proc/sys/net/ipv4/ip_forward # 0이면 활성화 필요 # 2. LXC 라우팅 규칙 확인 pct exec 103 -- ip route | grep 100.64 # 없으면 라우팅 규칙 추가 필요 # 3. 호스트 Tailscale 상태 확인 tailscale status # 대상 노드가 활성 상태인지 확인 ``` ### 문제 2: Caddy에서 502 Bad Gateway **증상:** ```bash curl -I https://p2.pharmq.kr # HTTP/2 502 ``` **해결책:** ```bash # 1. LXC에서 직접 연결 테스트 pct exec 103 -- curl -I --connect-timeout 5 https://100.64.0.3:8006 # 2. Caddy 로그 확인 pct exec 103 -- journalctl -u caddy --since "1 minute ago" # 3. 대상 서버 응답 확인 curl -I --connect-timeout 5 https://100.64.0.3:8006 ``` ### 문제 3: SSL 인증서 오류 **증상:** ``` transport http { dial_timeout 10s } ``` **해결책:** ```caddyfile # HTTPS 백엔드의 경우 SSL 검증 무시 추가 reverse_proxy https://100.64.0.3:8006 { transport http { tls_insecure_skip_verify } } ``` ## 📋 체크리스트 ### 설정 전 확인사항 - [ ] 호스트에 Tailscale 설치 및 활성화됨 - [ ] LXC 컨테이너 네트워크 설정 확인 - [ ] 대상 Tailscale 노드들이 활성 상태 ### 설정 단계 체크리스트 - [ ] 호스트 IP 포워딩 활성화 - [ ] LXC에서 Tailscale 네트워크 라우팅 추가 - [ ] LXC에서 Tailscale IP로 ping 성공 - [ ] Caddyfile에 올바른 Tailscale IP 설정 - [ ] HTTPS 백엔드에 `tls_insecure_skip_verify` 추가 - [ ] Caddy 설정 검증 및 리로드 - [ ] 외부에서 도메인 접근 테스트 성공 ## 🎯 핵심 포인트 ### 1. LXC에 Tailscale 설치 불필요 - **잘못된 접근**: LXC에 Tailscale 직접 설치 - **올바른 접근**: 호스트 Tailscale을 통한 라우팅 ### 2. 네트워크 라우팅이 핵심 ```bash # 이 명령어가 모든 것을 해결합니다 pct exec 103 -- ip route add 100.64.0.0/10 via 192.168.0.200 ``` ### 3. 호스트 기준 IP 사용 - LXC 내부 Tailscale 상태가 아닌 **호스트 Tailscale 상태** 기준으로 IP 설정 ### 4. HTTPS 백엔드 처리 ```caddyfile # PVE와 같은 HTTPS 백엔드의 경우 필수 transport http { tls_insecure_skip_verify } ``` ## 🚀 확장 가능성 ### 다른 서비스 추가 ```caddyfile # 새로운 Tailscale 노드 추가 예시 newservice.pharmq.kr { reverse_proxy http://100.64.0.X:PORT tls { dns cloudflare YOUR_TOKEN } } ``` ### 자동화 스크립트 ```bash #!/bin/bash # setup-lxc-tailscale-routing.sh LXC_ID="103" HOST_IP="192.168.0.200" TAILSCALE_NETWORK="100.64.0.0/10" # IP 포워딩 활성화 echo 1 > /proc/sys/net/ipv4/ip_forward # LXC 라우팅 추가 pct exec $LXC_ID -- ip route add $TAILSCALE_NETWORK via $HOST_IP echo "✅ LXC Tailscale 라우팅 설정 완료" ``` ## 📝 유지보수 ### 정기 점검 항목 1. **Tailscale 연결 상태**: `tailscale status` 2. **LXC 라우팅 상태**: `pct exec 103 -- ip route | grep 100.64` 3. **Caddy 도메인 목록**: `pct exec 103 -- journalctl -u caddy | grep domains` ### 재부팅 후 복구 ```bash # 호스트 재부팅 후 실행할 명령어들 (3단계 모두 필수!) echo 1 > /proc/sys/net/ipv4/ip_forward pct exec 103 -- ip route add 100.64.0.0/10 via 192.168.0.200 iptables -t nat -A POSTROUTING -s 192.168.0.19 -d 100.64.0.0/10 -j MASQUERADE ``` ## 🎉 결론 이 방법을 사용하면: - ✅ **LXC에 Tailscale 설치 불필요** - ✅ **간단한 네트워크 라우팅으로 해결** - ✅ **호스트 Tailscale 리소스 효율적 활용** - ✅ **SSL 인증서 자동 관리** - ✅ **확장성 및 유지보수성 우수** **핵심 원리**: 호스트가 이미 Tailscale 네트워크에 연결되어 있다면, LXC는 **라우팅 + MASQUERADE**를 통해 호스트를 경유하여 접근할 수 있습니다! **⚠️ 중요 교훈**: MASQUERADE 없이는 일부 Tailscale 노드 연결이 실패할 수 있습니다. 반드시 3단계 모두 필요합니다! --- **작성자**: Claude Code Assistant **파일 위치**: `/srv/pq_setup/LXC_Caddy_with_Host_Tailscale_Setup_Guide.md` **최종 업데이트**: 2025년 9월 22일