diff --git a/README.md b/README.md new file mode 100644 index 0000000..866ed48 --- /dev/null +++ b/README.md @@ -0,0 +1,105 @@ +# πŸš€ Headscale + Headplane Docker Setup + +Tailscale을 μ™„μ „νžˆ λŒ€μ²΄ν•˜λŠ” 자체 ν˜ΈμŠ€νŒ… μ†”λ£¨μ…˜ + +## πŸ“ 파일 ꡬ쑰 +``` +/srv/ +β”œβ”€β”€ docker-compose.yml # Docker Compose μ„€μ • +β”œβ”€β”€ .env # ν™˜κ²½λ³€μˆ˜ +β”œβ”€β”€ start.sh # μžλ™ μ„€μΉ˜ 슀크립트 +β”œβ”€β”€ config/ +β”‚ └── config.yaml # Headscale μ„€μ • +β”œβ”€β”€ data/ # λ°μ΄ν„°λ² μ΄μŠ€ 및 ν‚€ 파일 +└── run/ # λŸ°νƒ€μž„ 파일 +``` + +## πŸš€ λΉ λ₯Έ μ‹œμž‘ + +### 1. μžλ™ μ„€μΉ˜ (ꢌμž₯) +```bash +chmod +x /srv/start.sh +/srv/start.sh +``` + +### 2. μˆ˜λ™ μ„€μΉ˜ +```bash +# 1. Headscale μ‹œμž‘ +docker-compose up -d headscale + +# 2. API ν‚€ 생성 +docker-compose exec headscale headscale apikeys create + +# 3. .env νŒŒμΌμ— API ν‚€ μž…λ ₯ +vi .env + +# 4. Headplane μ‹œμž‘ +docker-compose up -d headplane +``` + +## πŸ“‹ 접속 정보 +- **Headscale API**: http://localhost:8080 +- **Headplane UI**: http://localhost:3000 + +## πŸ‘€ μ‚¬μš©μž 관리 + +### μ‚¬μš©μž 생성 +```bash +docker-compose exec headscale headscale users create myuser +``` + +### Pre-auth ν‚€ 생성 +```bash +docker-compose exec headscale headscale preauthkeys create --user myuser --reusable --expiration 24h +``` + +## πŸ“± ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° + +### Linux/macOS +```bash +# Tailscale ν΄λΌμ΄μ–ΈνŠΈ μ„€μΉ˜ ν›„ +tailscale up --login-server=http://localhost:8080 +``` + +### Windows +```cmd +tailscale up --login-server=http://localhost:8080 +``` + +## πŸ”§ μœ μš©ν•œ λͺ…λ Ήμ–΄ + +### μƒνƒœ 확인 +```bash +docker-compose ps +docker-compose logs -f +``` + +### λ…Έλ“œ λͺ©λ‘ 확인 +```bash +docker-compose exec headscale headscale nodes list +``` + +### μ‚¬μš©μž λͺ©λ‘ 확인 +```bash +docker-compose exec headscale headscale users list +``` + +## πŸ› οΈ νŠΈλŸ¬λΈ”μŠˆνŒ… + +### μ»¨ν…Œμ΄λ„ˆ μž¬μ‹œμž‘ +```bash +docker-compose restart +``` + +### 둜그 확인 +```bash +docker-compose logs headscale +docker-compose logs headplane +``` + +### μ™„μ „ μ΄ˆκΈ°ν™” +```bash +docker-compose down +sudo rm -rf data/* +docker-compose up -d +``` \ No newline at end of file diff --git a/config/config.yaml b/config/config.yaml new file mode 100644 index 0000000..ed7478a --- /dev/null +++ b/config/config.yaml @@ -0,0 +1,69 @@ +--- +server_url: http://localhost:8080 +listen_addr: 0.0.0.0:8080 +metrics_listen_addr: 0.0.0.0:9090 + +private_key_path: /var/lib/headscale/private.key +noise: + private_key_path: /var/lib/headscale/noise_private.key + +ip_prefixes: + - 100.64.0.0/10 + +derp: + server: + enabled: false + urls: + - https://controlplane.tailscale.com/derpmap/default + +disable_check_updates: false +ephemeral_node_inactivity_timeout: 30m +database: + type: sqlite3 + sqlite: + path: /var/lib/headscale/db.sqlite + +acme_url: https://acme-v02.api.letsencrypt.org/directory +acme_email: "" + +tls_letsencrypt_hostname: "" +tls_letsencrypt_cache_dir: /var/lib/headscale/cache +tls_letsencrypt_challenge_type: HTTP-01 +tls_letsencrypt_listen: ":http" + +tls_cert_path: "" +tls_key_path: "" + +log: + format: text + level: info + +acl_policy_path: "" + +dns_config: + override_local_dns: true + nameservers: + - 1.1.1.1 + - 8.8.8.8 + domains: [] + magic_dns: true + base_domain: headscale.local + +unix_socket: /var/run/headscale/headscale.sock +unix_socket_permission: "0770" + +logtail: + enabled: false + +randomize_client_port: false + +oidc: + only_start_if_oidc_is_available: true + issuer: "" + client_id: "" + client_secret: "" + scope: ["openid", "profile", "email"] + extra_params: {} + allowed_domains: [] + allowed_users: [] + strip_email_domain: true \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..aec3bfd --- /dev/null +++ b/start.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +echo "πŸš€ Headscale + Headplane μ„€μΉ˜ μ‹œμž‘..." + +# Docker 및 Docker Compose μ„€μΉ˜ 확인 +if ! command -v docker &> /dev/null; then + echo "❌ Dockerκ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. Dockerλ₯Ό λ¨Όμ € μ„€μΉ˜ν•΄μ£Όμ„Έμš”." + exit 1 +fi + +if ! command -v docker-compose &> /dev/null; then + echo "❌ Docker Composeκ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. Docker Composeλ₯Ό λ¨Όμ € μ„€μΉ˜ν•΄μ£Όμ„Έμš”." + exit 1 +fi + +echo "βœ… Docker ν™˜κ²½ 확인 μ™„λ£Œ" + +# μ»¨ν…Œμ΄λ„ˆ μ‹œμž‘ +echo "πŸ“¦ Headscale μ»¨ν…Œμ΄λ„ˆ μ‹œμž‘..." +docker-compose up -d headscale + +# Headscale이 μ‹œμž‘λ  λ•ŒκΉŒμ§€ λŒ€κΈ° +echo "⏳ Headscale μ„œλΉ„μŠ€ μ‹œμž‘ λŒ€κΈ° 쀑..." +sleep 10 + +# API ν‚€ 생성 +echo "πŸ”‘ API ν‚€ 생성..." +API_KEY=$(docker-compose exec -T headscale headscale apikeys create | grep -o 'hs_[a-zA-Z0-9]*') + +if [ -z "$API_KEY" ]; then + echo "❌ API ν‚€ 생성 μ‹€νŒ¨. μˆ˜λ™μœΌλ‘œ μƒμ„±ν•΄μ£Όμ„Έμš”:" + echo "docker-compose exec headscale headscale apikeys create" + exit 1 +fi + +echo "βœ… API ν‚€ 생성 μ™„λ£Œ: $API_KEY" + +# .env 파일 μ—…λ°μ΄νŠΈ +sed -i "s/HEADSCALE_API_KEY=your_api_key_here/HEADSCALE_API_KEY=$API_KEY/" .env + +echo "🌐 Headplane μ›Ή UI μ‹œμž‘..." +docker-compose up -d headplane + +echo "" +echo "πŸŽ‰ μ„€μΉ˜ μ™„λ£Œ!" +echo "" +echo "πŸ“‹ 접속 정보:" +echo " - Headscale API: http://localhost:8080" +echo " - Headplane UI: http://localhost:3000" +echo " - API ν‚€: $API_KEY" +echo "" +echo "πŸ“– λ‹€μŒ 단계:" +echo " 1. 첫 번째 μ‚¬μš©μž 생성:" +echo " docker-compose exec headscale headscale users create myuser" +echo "" +echo " 2. Pre-auth ν‚€ 생성:" +echo " docker-compose exec headscale headscale preauthkeys create --user myuser --reusable --expiration 24h" +echo "" +echo " 3. ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²°:" +echo " tailscale up --login-server=http://localhost:8080" +echo "" +echo "πŸ“Š μƒνƒœ 확인:" +echo " docker-compose ps" +echo " docker-compose logs -f" \ No newline at end of file