[Security] 若主機有對 Internet,且系統和 SQL Server 同一台,則不應打開 SQL Server TCP 1433 Port

網路上有些文章會教學員在安裝完 SQL Server 後,一併打開 TCP Port 1433,但若主機有對 Internet,且系統和 SQL Server 同一台,這反而是個很危險的行為。

只要是 Internet-facing (對 Internet 開放) 的系統如 Web 應用程式,基本上就是駭客下手的目標之一,不管是僅僅刺探情報或是真的發動攻擊,而資料庫是駭客最想要取得的重點資源,不論是要竊取資料或是要破壞資料,然後在裡面放個後門之類的,而若系統和資料庫又在同一台,而且也開了 TCP Port,那麼等於是把資料庫也暴露在 Internet 上,讓駭客能不經由 Web 應用程式的控管而直接連結資料庫,不管這個動作是否成功,它都會吃掉部份的 I/O 資源,而且駭客最愛用暴力破解法,暴力破解加上類似 DDoS 的攻擊,不管駭客有沒有成功破解,資料庫就會先被打掛了。

SQL Server 預設有三種連線方式,一種是 TCP/IP,一種是具名管道 (Named Pipe),這是經由記憶體內的通道連線的機制,這已經有一定程度的安全性了,但具名管道設定起來相對有一點點小複雜,因此才又多出了一個最簡單的連線方式:共享記憶體 (Shared Memory),它可以在不用做任何設定的情況下就可連線資料庫,也是預設開啟的連線方式 (TCP預設是關閉),而使用具名管道或共享記憶體,都可以避免因走 TCP/IP 所發生的 I/O 效能損耗,更可以少一個給駭客攻擊的管道,因此若主機有對 Internet,且系統和 SQL Server 同一台時,請使用共享記憶體連線,不要開啟 TCP Port

使用共享記憶體的連線字串非常簡單,只要這樣寫就好:

使用 SQL Server 驗證:
initial catalog=[資料庫名稱]; user id=aaaa; password=bbb
或是使用 Windows 驗證 (更安全):
initial catalog=[資料庫名稱]; integrated security=true (或SSPI也行)

若一定要加上 data source,則使用 localhost 不要用 (local) (原因可參考:使用共用記憶體通訊協定建立有效的連接字串 - SQL Server | Microsoft Docs)

使用 SQL Server 驗證:
data source=localhost; initial catalog=[資料庫名稱]; user id=aaaa; password=bbb
或是使用 Windows 驗證 (更安全):
data source=localhost; initial catalog=[資料庫名稱]; integrated security=true (或SSPI也行)

同場加映:使用 PowerShell 開啟或關閉 TCP 連線 (How to enable the TCP protocol using SQLPS - SQL Server | Microsoft Docs)

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SqlWmiManagement')
$wmi = New-Object 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' localhost

# 闗閉或開啟 TCP Port
$tcp = $wmi.ServerInstances['MSSQLSERVER'].ServerProtocols['Tcp']
$tcp.IsEnabled = $false # $true 表示開啟 
$tcp.Alter()  

# 重啟 SQL Server 服務
Restart-Service -Name MSSQLSERVER -Force

同場加映:使用指令操作 Windows 防火牆,建立、刪除、停用與封鎖 TCP Port 1433 (以下例子的規則名稱以 "SQL Server" 為例)

建立規則:
netsh advfirewall firewall add rule name="SQL Server" dir=in action=allow protocol=TCP localport=1433
更新規則,封鎖 TCP 1433:
netsh advfirewall firewall set rule name="SQL Server" new action=block
關閉規則:
netsh advfirewall firewall set rule name="SQL Server" new enable=no
刪除規則
netsh advfirewall firewall delete rule name="SQL Server"
注意,本篇所說不要開啟 TCP Port 1433 只是少一個攻擊面向,不能因為這樣就不做其他的防護措施,否則若駭客成功以合法的方式存取 Web 應用程式時,仍然會有機會連線並竊取資料庫內的資料。