Multi-Level Subdomains Implementation: DNS Configuration, Cookie Behavior & Doc Root Management


2 views

Implementing multi-level subdomains like sub2.sub1.example.com requires understanding several technical aspects:

From a DNS perspective, each level functions as a separate subdomain. You'll need either:

; DNS zone file example for BIND
*.sub1        IN  CNAME  example.com.
sub2.sub1     IN  A      192.0.2.1

Or modern solutions like wildcard DNS entries. Most hosting providers support this through their control panels.

For Apache:


    ServerName sub2.sub1.example.com
    DocumentRoot /var/www/sub2_sub1
    # Cookie settings
    php_value session.cookie_domain .example.com

Cookies follow domain hierarchy rules:

// Setting cookie for entire domain tree
document.cookie = "prefs=dark_mode; domain=.example.com; path=/";

// Will be accessible at:
// - example.com
// - sub1.example.com 
// - sub2.sub1.example.com

Three common approaches:

  1. Separate root for each level (/var/www/sub2_sub1)
  2. Dynamic routing (PHP/Node.js example):
// Express.js example
app.use((req, res) => {
  const parts = req.hostname.split('.');
  const content = getContentForLevels(parts);
  res.send(content);
});

Implement 301 redirects:

# Nginx config
server {
    listen 80;
    server_name ~^(?!www\.)(?.+)\.example\.com$;
    return 301 $scheme://www.$sub.example.com$request_uri;
}

Each DNS lookup adds latency. Benchmark with tools:

dig +trace sub2.sub1.example.com
curl -o /dev/null -s -w "%{time_namelookup}\n" https://sub2.sub1.example.com

html

Yes, multi-level subdomains like sub2.sub1.example.com are fully supported in DNS specifications (RFC 1034). Implementation depends on:

  • DNS provider capabilities (AWS Route 53, Cloudflare, etc.)
  • Web server configuration (Apache/Nginx virtual hosts)
  • Wildcard SSL certificate coverage

Each level represents a separate subdomain in the hierarchy:

domain.com          (root domain)
├── sub1.domain.com (1st-level)
│   └── sub2.sub1.domain.com (2nd-level)
└── www.domain.com  (common alias)

Technically sub2.sub1 is a subdomain of sub1, but browsers treat each level as a distinct domain for security policies.

Web servers handle docroots differently:


# Apache configuration example
<VirtualHost *:80>
    ServerName sub2.sub1.domain.com
    DocumentRoot /var/www/sub2_sub1
    # Other directives...
</VirtualHost>

# Nginx configuration example
server {
    listen 80;
    server_name sub2.sub1.domain.com;
    root /var/www/sub2_sub1;
    # Additional config...
}

Best practice for canonical URLs:


# .htaccess canonical redirect
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# Nginx equivalent
server {
    listen 80;
    server_name www.sub1.domain.com;
    return 301 $scheme://sub1.domain.com$request_uri;
}

Cookie behavior follows these rules:


// Cookie set on domain.com (accessible by all subdomains)
document.cookie = "global=value; domain=.domain.com; path=/";

// Cookie set on sub1.domain.com (only accessible by *.sub1.domain.com)
document.cookie = "nested=value; domain=.sub1.domain.com; path=/";

// Isolation example (sub2.sub1 cannot read sub1 cookies without explicit scope)
console.log(document.cookie); // Shows only cookies scoped to current level
  • SSL Certificate Coverage: Requires wildcard cert (*.domain.com) or multi-level wildcard (*.*.domain.com)
  • DNS Propagation: Multi-level changes may take longer to propagate globally
  • CORS Policies: Requires explicit headers for cross-subdomain API calls
  • Analytics Tracking: May need cross-domain tracking configuration

Complete AWS Route53 + Nginx setup:


# DNS Record (Route53)
sub2.sub1 IN A 192.0.2.1

# Nginx full configuration
server {
    listen 443 ssl http2;
    server_name sub2.sub1.domain.com;
    
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    
    root /sites/sub2_sub1/public;
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    # Security headers for subdomain isolation
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
}