Skip to content

Commit fe131a0

Browse files
committed
fix(nginx-proxy): Correct wildcard htpasswd lookup for 3-part domains
Fix bug where blog.example.com incorrectly checked for _wildcard.blog.example.com instead of _wildcard.example.com. Changes: - 4+ part domains: check 3-part wildcard first, then 2-part fallback - 2-3 part domains: check 2-part wildcard directly - Fixed template formatting to match original style - Updated README with corrected lookup table
1 parent a21ca47 commit fe131a0

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

nginx-proxy/README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ This file will apply HTTP auth to:
4848
The template checks for htpasswd files in this order:
4949

5050
1. **Exact match**: `/etc/nginx/htpasswd/blog.domain.com`
51-
2. **Wildcard (3 parts)**: `/etc/nginx/htpasswd/_wildcard.domain.com` (for multi-level TLD support)
52-
3. **Wildcard (2 parts)**: `/etc/nginx/htpasswd/_wildcard.com` (fallback)
51+
2. **Wildcard (3 parts)**: `/etc/nginx/htpasswd/_wildcard.domain.co.in` (for 4+ part domains only)
52+
3. **Wildcard (2 parts)**: `/etc/nginx/htpasswd/_wildcard.example.com` (for 2-3 part domains, or fallback)
5353
4. **Default**: `/etc/nginx/htpasswd/default`
5454

5555
#### Example Setup
@@ -58,19 +58,25 @@ The template checks for htpasswd files in this order:
5858
# Create wildcard htpasswd for WordPress multisite
5959
htpasswd -c /etc/nginx/htpasswd/_wildcard.example.com admin
6060

61+
# This protects: example.com, blog.example.com, shop.example.com, etc.
62+
6163
# Optional: Override for a specific subdomain
6264
htpasswd -c /etc/nginx/htpasswd/api.example.com api_user
6365
```
6466

6567
#### Multi-level TLDs
6668

67-
Multi-level TLDs (e.g., `.co.in`, `.com.au`) are fully supported. The template checks progressively:
69+
Multi-level TLDs (e.g., `.co.in`, `.com.au`) are fully supported:
6870

69-
1. **Last 3 parts first**: `_wildcard.domain.co.in` for `blog.domain.co.in`
70-
2. **Then last 2 parts**: `_wildcard.co.in` as fallback
71+
| Host | Wildcard File Checked |
72+
|------|----------------------|
73+
| `blog.domain.co.in` (4 parts) | `_wildcard.domain.co.in` first, then `_wildcard.co.in` |
74+
| `domain.co.in` (3 parts) | `_wildcard.co.in` |
75+
| `blog.example.com` (3 parts) | `_wildcard.example.com` |
76+
| `example.com` (2 parts) | `_wildcard.example.com` |
7177

7278
```bash
73-
# For domain.co.in multisite
79+
# For domain.co.in multisite (multi-level TLD)
7480
htpasswd -c /etc/nginx/htpasswd/_wildcard.domain.co.in admin
7581

7682
# This will protect:

nginx-proxy/nginx.tmpl

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@
6767
Supports multi-level TLDs: _wildcard.domain.co.in works for domain.co.in AND *.domain.co.in
6868
6969
Lookup order (after exact match check on line 56):
70-
- For 3+ part domains: checks _wildcard.{last-3-parts}, then falls back to default
71-
- For 2-part domains: checks _wildcard.{domain}, then falls back to default
70+
- For 4+ part domains: checks _wildcard.{last-3-parts}, then _wildcard.{last-2-parts}, then default
71+
- For 2-3 part domains: checks _wildcard.{last-2-parts}, then falls back to default
7272
- For single-part hostnames: uses default only
7373
7474
Note: Uses sprig's splitList and sub functions (available in docker-gen 0.7.4+)
7575
*/}}
7676
{{ else }}
7777
{{ $hostParts := splitList "." .Host }}
7878
{{ $partsLen := len $hostParts }}
79-
{{/* Check last 3 parts first (e.g., domain.co.in for blog.domain.co.in) */}}
80-
{{ if ge $partsLen 3 }}
79+
{{/* For 4+ part domains, check last 3 parts first (e.g., _wildcard.domain.co.in for blog.domain.co.in) */}}
80+
{{ if ge $partsLen 4 }}
8181
{{ $idx3 := sub $partsLen 3 }}
8282
{{ $idx2 := sub $partsLen 2 }}
8383
{{ $idx1 := sub $partsLen 1 }}
@@ -91,17 +91,30 @@
9191
{{ else if (exists "/etc/nginx/vhost.d/default_acl") }}
9292
include /etc/nginx/vhost.d/default_acl;
9393
{{ end }}
94-
{{ else if (exists "/etc/nginx/htpasswd/default") }}
95-
auth_basic "Restricted {{ .Host }}";
96-
auth_basic_user_file /etc/nginx/htpasswd/default;
97-
{{ if (exists (printf "/etc/nginx/vhost.d/%s_acl" .Host)) }}
98-
include {{ printf "/etc/nginx/vhost.d/%s_acl" .Host}};
99-
{{ else if (exists "/etc/nginx/vhost.d/default_acl") }}
100-
include /etc/nginx/vhost.d/default_acl;
94+
{{ else }}
95+
{{/* Fallback: check last 2 parts (e.g., _wildcard.co.in for blog.domain.co.in) */}}
96+
{{ $baseDomain2 := printf "%s.%s" (index $hostParts $idx2) (index $hostParts $idx1) }}
97+
{{ $wildcardHtpasswd2 := printf "/etc/nginx/htpasswd/_wildcard.%s" $baseDomain2 }}
98+
{{ if (exists $wildcardHtpasswd2) }}
99+
auth_basic "Restricted {{ .Host }}";
100+
auth_basic_user_file {{ ($wildcardHtpasswd2) }};
101+
{{ if (exists (printf "/etc/nginx/vhost.d/%s_acl" .Host)) }}
102+
include {{ printf "/etc/nginx/vhost.d/%s_acl" .Host}};
103+
{{ else if (exists "/etc/nginx/vhost.d/default_acl") }}
104+
include /etc/nginx/vhost.d/default_acl;
105+
{{ end }}
106+
{{ else if (exists "/etc/nginx/htpasswd/default") }}
107+
auth_basic "Restricted {{ .Host }}";
108+
auth_basic_user_file /etc/nginx/htpasswd/default;
109+
{{ if (exists (printf "/etc/nginx/vhost.d/%s_acl" .Host)) }}
110+
include {{ printf "/etc/nginx/vhost.d/%s_acl" .Host}};
111+
{{ else if (exists "/etc/nginx/vhost.d/default_acl") }}
112+
include /etc/nginx/vhost.d/default_acl;
113+
{{ end }}
101114
{{ end }}
102115
{{ end }}
103116
{{ else if ge $partsLen 2 }}
104-
{{/* Only 2 parts (e.g., domain.com) - check wildcard directly */}}
117+
{{/* For 2-3 part domains, check last 2 parts (e.g., _wildcard.example.com for blog.example.com or example.com) */}}
105118
{{ $idx2 := sub $partsLen 2 }}
106119
{{ $idx1 := sub $partsLen 1 }}
107120
{{ $baseDomain2 := printf "%s.%s" (index $hostParts $idx2) (index $hostParts $idx1) }}

0 commit comments

Comments
 (0)