Skip to content

Commit a66e9be

Browse files
authored
Merge pull request #48 from Dstack-TEE/ingress-dns-providers
ingress: Adds support for linode dns provider
2 parents d51afb0 + 4123b2e commit a66e9be

File tree

17 files changed

+1532
-391
lines changed

17 files changed

+1532
-391
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.claude/
2+
/CLAUDE.md
3+
/test/
4+
__pycache__
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# DNS Provider Configuration Guide
2+
3+
This guide explains how to configure dstack-ingress to work with different DNS providers for managing custom domains and SSL certificates.
4+
5+
## Supported DNS Providers
6+
7+
- **Cloudflare** - The original and default provider
8+
- **Linode DNS** - For Linode-hosted domains
9+
10+
## Environment Variables
11+
12+
### Common Variables (Required for all providers)
13+
14+
- `DOMAIN` - Your custom domain (e.g., `app.example.com`)
15+
- `GATEWAY_DOMAIN` - dstack gateway domain (e.g., `_.dstack-prod5.phala.network`)
16+
- `CERTBOT_EMAIL` - Email for Let's Encrypt registration
17+
- `TARGET_ENDPOINT` - Backend application endpoint to proxy to
18+
- `DNS_PROVIDER` - DNS provider to use (`cloudflare`, `linode`)
19+
20+
### Optional Variables
21+
22+
- `SET_CAA` - Enable CAA record setup (default: false)
23+
- `PORT` - HTTPS port (default: 443)
24+
- `TXT_PREFIX` - Prefix for TXT records (default: "_tapp-address")
25+
26+
## Provider-Specific Configuration
27+
28+
### Cloudflare
29+
30+
```bash
31+
DNS_PROVIDER=cloudflare
32+
CLOUDFLARE_API_TOKEN=your-api-token
33+
```
34+
35+
**Required Permissions:**
36+
- Zone:Read
37+
- DNS:Edit
38+
39+
### Linode DNS
40+
41+
```bash
42+
DNS_PROVIDER=linode
43+
LINODE_API_TOKEN=your-api-token
44+
```
45+
46+
**Required Permissions:**
47+
- Domains: Read/Write access
48+
49+
**Important Note for Linode:**
50+
- Linode has a limitation where CAA and CNAME records cannot coexist on the same subdomain
51+
- To work around this, the system will attempt to use A records instead of CNAME records
52+
- If the gateway domain can be resolved to an IP, an A record will be created
53+
- If resolution fails, it falls back to CNAME (but CAA records won't work on that subdomain)
54+
- This is a Linode-specific limitation not present in other providers
55+
56+
## Docker Compose Example
57+
58+
```yaml
59+
version: '3.8'
60+
61+
services:
62+
ingress:
63+
image: dstack-ingress:latest
64+
ports:
65+
- "443:443"
66+
environment:
67+
# Common configuration
68+
- DNS_PROVIDER=linode
69+
- DOMAIN=app.example.com
70+
- GATEWAY_DOMAIN=_.dstack-prod5.phala.network
71+
72+
- TARGET_ENDPOINT=http://backend:8080
73+
74+
# Linode specific
75+
- LINODE_API_TOKEN=your-api-token
76+
volumes:
77+
- ./letsencrypt:/etc/letsencrypt
78+
- ./evidences:/evidences
79+
```
80+
81+
## Migration from Cloudflare-only Setup
82+
83+
If you're currently using the Cloudflare-only version:
84+
85+
1. **No changes needed for Cloudflare users** - The default behavior remains Cloudflare
86+
2. **For other providers** - Add the `DNS_PROVIDER` environment variable and provider-specific credentials
87+
88+
## Troubleshooting
89+
90+
### DNS Provider Detection
91+
92+
If you see "Could not detect DNS provider type", ensure you have either:
93+
- Set `DNS_PROVIDER` environment variable explicitly, OR
94+
- Set provider-specific credential environment variables (e.g., `CLOUDFLARE_API_TOKEN`)
95+
96+
### Certificate Generation Issues
97+
98+
Different providers may have different propagation times. The default is 120 seconds, but you may need to adjust based on your provider's behavior.
99+
100+
### Permission Errors
101+
102+
Ensure your API tokens/credentials have the necessary permissions listed above for your provider.
103+
104+
## API Token Generation
105+
106+
### Cloudflare
107+
1. Go to https://dash.cloudflare.com/profile/api-tokens
108+
2. Create token with Zone:Read and DNS:Edit permissions
109+
3. Scope to specific zones if desired
110+
111+
### Linode
112+
1. Go to https://cloud.linode.com/profile/tokens
113+
2. Create a Personal Access Token
114+
3. Grant "Domains" Read/Write access

custom-domain/dstack-ingress/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ RUN set -e; \
3232

3333
RUN mkdir -p /etc/letsencrypt /var/www/certbot /usr/share/nginx/html
3434

35-
COPY ./scripts/* /scripts/
36-
RUN chmod +x /scripts/*
35+
COPY ./scripts /scripts/
36+
RUN chmod +x /scripts/*.sh /scripts/*.py
3737
ENV PATH="/scripts:$PATH"
38+
ENV PYTHONPATH="/scripts"
3839
COPY .GIT_REV /etc/
3940

4041
ENTRYPOINT ["/scripts/entrypoint.sh"]

custom-domain/dstack-ingress/README.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# Custom Domain Setup for dstack Applications
22

3-
This repository provides a solution for setting up custom domains with automatic SSL certificate management for dstack applications using Cloudflare DNS and Let's Encrypt.
3+
This repository provides a solution for setting up custom domains with automatic SSL certificate management for dstack applications using various DNS providers and Let's Encrypt.
44

55
## Overview
66

77
This project enables you to run dstack applications with your own custom domain, complete with:
88

99
- Automatic SSL certificate provisioning and renewal via Let's Encrypt
10-
- Cloudflare DNS configuration for CNAME, TXT, and CAA records
10+
- Multi-provider DNS support (Cloudflare, Linode DNS, more to come)
11+
- Automatic DNS configuration for CNAME, TXT, and CAA records
1112
- Nginx reverse proxy to route traffic to your application
1213
- Certificate evidence generation for verification
1314
- Strong SSL/TLS configuration with modern cipher suites (AES-GCM and ChaCha20-Poly1305)
@@ -17,16 +18,20 @@ This project enables you to run dstack applications with your own custom domain,
1718
The dstack-ingress system provides a seamless way to set up custom domains for dstack applications with automatic SSL certificate management. Here's how it works:
1819

1920
1. **Initial Setup**:
21+
2022
- When first deployed, the container automatically obtains SSL certificates from Let's Encrypt using DNS validation
21-
- It configures Cloudflare DNS by creating necessary CNAME, TXT, and optional CAA records
23+
- It configures your DNS provider by creating necessary CNAME, TXT, and optional CAA records
2224
- Nginx is configured to use the obtained certificates and proxy requests to your application
2325

2426
2. **DNS Configuration**:
27+
2528
- A CNAME record is created to point your custom domain to the dstack gateway domain
2629
- A TXT record is added with application identification information to help dstack-gateway to route traffic to your application
2730
- If enabled, CAA records are set to restrict which Certificate Authorities can issue certificates for your domain
31+
- The system automatically detects your DNS provider based on environment variables
2832

2933
3. **Certificate Management**:
34+
3035
- SSL certificates are automatically obtained during initial setup
3136
- A scheduled task runs twice daily to check for certificate renewal
3237
- When certificates are renewed, Nginx is automatically reloaded to use the new certificates
@@ -40,7 +45,8 @@ The dstack-ingress system provides a seamless way to set up custom domains for d
4045

4146
### Prerequisites
4247

43-
- Host your domain on Cloudflare and have access to the Cloudflare account with API token
48+
- Host your domain on one of the supported DNS providers
49+
- Have appropriate API credentials for your DNS provider (see [DNS Provider Configuration](DNS_PROVIDERS.md) for details)
4450

4551
### Deployment
4652

@@ -57,7 +63,13 @@ services:
5763
ports:
5864
- "443:443"
5965
environment:
66+
# DNS Provider
67+
- DNS_PROVIDER=cloudflare
68+
69+
# Cloudflare example
6070
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
71+
72+
# Common configuration
6173
- DOMAIN=${DOMAIN}
6274
- GATEWAY_DOMAIN=${GATEWAY_DOMAIN}
6375
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
@@ -68,21 +80,23 @@ services:
6880
- cert-data:/etc/letsencrypt
6981
restart: unless-stopped
7082
app:
71-
image: nginx # Replace with your application image
83+
image: nginx # Replace with your application image
7284
restart: unless-stopped
7385
volumes:
74-
cert-data: # Persistent volume for certificates
86+
cert-data: # Persistent volume for certificates
7587
```
7688
77-
Explanation of environment variables:
89+
**Core Environment Variables:**
7890
79-
- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API token
91+
- `DNS_PROVIDER`: DNS provider to use (cloudflare, linode)
8092
- `DOMAIN`: Your custom domain
81-
- `GATEWAY_DOMAIN`: The dstack gateway domain. (e.g. `_.dstack-prod5.phala.network` for Phala Cloud)
93+
- `GATEWAY_DOMAIN`: The dstack gateway domain (e.g. `_.dstack-prod5.phala.network` for Phala Cloud)
8294
- `CERTBOT_EMAIL`: Your email address used in Let's Encrypt certificate requests
8395
- `TARGET_ENDPOINT`: The plain HTTP endpoint of your dstack application
8496
- `SET_CAA`: Set to `true` to enable CAA record setup
8597

98+
For provider-specific configuration details, see [DNS Provider Configuration](DNS_PROVIDERS.md).
99+
86100
#### Option 2: Build Your Own Image
87101

88102
If you prefer to build the image yourself:
@@ -95,6 +109,7 @@ If you prefer to build the image yourself:
95109
```
96110

97111
**Important**: You must use the `build-image.sh` script to build the image. This script ensures reproducible builds with:
112+
98113
- Specific buildkit version (v0.20.2)
99114
- Deterministic timestamps (`SOURCE_DATE_EPOCH=0`)
100115
- Package pinning for consistency
@@ -150,10 +165,12 @@ The dstack-ingress system provides mechanisms to verify and attest that your cus
150165
When certificates are issued or renewed, the system automatically generates a set of cryptographically linked evidence files:
151166

152167
1. **Access Evidence Files**:
168+
153169
- Evidence files are accessible at `https://your-domain.com/evidences/`
154170
- Key files include `acme-account.json`, `cert.pem`, `sha256sum.txt`, and `quote.json`
155171

156172
2. **Verification Chain**:
173+
157174
- `quote.json` contains a TDX quote with the SHA-256 digest of `sha256sum.txt` embedded in the report_data field
158175
- `sha256sum.txt` contains cryptographic checksums of both `acme-account.json` and `cert.pem`
159176
- When the TDX quote is verified, it cryptographically proves the integrity of the entire evidence chain
@@ -178,9 +195,10 @@ The output will display CAA records that restrict certificate issuance exclusive
178195
All Let's Encrypt certificates are logged in public Certificate Transparency (CT) logs, enabling independent verification:
179196

180197
**CT Log Verification**:
181-
- Visit [crt.sh](https://crt.sh/) and search for your domain
182-
- Confirm that the certificates match those issued by the dstack-ingress system
183-
- This public logging ensures that all certificates are visible and can be monitored for unauthorized issuance
198+
199+
- Visit [crt.sh](https://crt.sh/) and search for your domain
200+
- Confirm that the certificates match those issued by the dstack-ingress system
201+
- This public logging ensures that all certificates are visible and can be monitored for unauthorized issuance
184202

185203
## License
186204

custom-domain/dstack-ingress/docker-compose.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ services:
2121

2222
volumes:
2323
cert-data:
24-

0 commit comments

Comments
 (0)