Best Practices: Should DMZ Web Servers Have MSSQL Database Access in LAN?


2 views

This architectural question divides security professionals and developers. While your networking team's position reflects a conservative security stance, the reality is more nuanced. Let's examine both perspectives with technical depth.

The classic three-legged firewall model typically enforces:

Internet → DMZ (Web Server) ← Firewall → LAN (Database)
           ↑                   ↓
           No direct return path

This creates a security choke point where:

  • DMZ hosts can receive inbound connections
  • LAN initiates outbound connections to DMZ
  • No direct DMZ→LAN communication exists

Modern web applications often require database access. Here are common solutions:

Option 1: Firewall Exception with Service Account

// Web server connection string with restricted credentials
string connString = "Server=lan-sql01;Database=AppDB;" + 
                    "User Id=dmz_web_user;Password=Complex!123;" +
                    "Application Name=DMZ_WebApp;" +
                    "Connection Timeout=30;";

Firewall rules would specify:

Source: DMZ_Web_IP (single host)
Destination: LAN_SQL_IP:1433
Protocol: TCP
Authentication: Domain\dmz_web_user
SQL Permissions: db_datareader, db_datawriter

Option 2: Middleware Service Layer

Implement a REST API in the LAN that the DMZ calls:

// Web server calling LAN API
public async Task GetOrderData(int orderId)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("https://lan-api.company.com/");
        client.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", apiToken);
        
        var response = await client.GetAsync($"/api/orders/{orderId}");
        return await response.Content.ReadAsAsync();
    }
}

If allowing direct access, implement these protections:

  • Network segmentation with VLANs
  • SQL Server encrypted connections (TLS 1.2+)
  • Row-level security policies in MSSQL
  • Connection filtering at SQL Server level
-- Example SQL Server firewall rule
CREATE ENDPOINT [DMZ_Web_Endpoint]
STATE = STARTED
AS TCP (LISTENER_PORT = 1433)
FOR TSQL();

Latency comparisons between architectures:

Approach Avg Latency Security Risk
Direct DMZ→LAN 5-15ms High
API Middleware 20-50ms Medium
Data Replication Varies Low

Large organizations often use:

Web Tier (DMZ) → Application Tier (DMZ-2) → Database Tier (LAN)
               ↑                        ↑
           External Auth            Internal Firewall

This creates defense-in-depth while maintaining functionality. The decision ultimately depends on your organization's risk tolerance and compliance requirements.


This is a classic security architecture question that divides many IT teams. Let's examine both perspectives:

The networking team's position follows conventional security best practices:


# Typical firewall rules (conceptual)
ALLOW: Internet → DMZ (port 80/443)
ALLOW: LAN → DMZ (various ports)
DENY: DMZ → LAN (all ports)

This creates a one-way trust relationship where the DMZ is treated as semi-trusted at best.

Web applications often require database access. Consider this ASP.NET connection scenario:


// Web.config connection string (DMZ web server to LAN SQL)
<connectionStrings>
    <add name="AppDB" 
         connectionString="Server=lan-sql01;Database=AppDB;User ID=webuser;Password=***" 
         providerName="System.Data.SqlClient"/>
</connectionStrings>

Instead of blanket rules, implement controlled access:


# Firewall rules for secure DMZ→LAN access
ALLOW: dmz-web01 → lan-sql01 (TCP 1433)
WITH:
- Source IP restriction
- Service account authentication
- Encrypted connection
- Logging all access attempts

When direct access isn't permitted, consider:


// Web service facade pattern
[WebMethod]
public DataSet GetCustomerData(int customerId)
{
    // LAN service processes request
    // DMZ only communicates via this controlled channel
}

If access is granted, implement robust monitoring:


-- SQL Server audit query
SELECT 
    login_name, 
    COUNT(*) as connection_count,
    MAX(connect_time) as last_attempt
FROM sys.dm_exec_sessions
WHERE host_name LIKE 'dmz-web%'
GROUP BY login_name
ORDER BY connection_count DESC;