demoshop

demo, trying to be the best_

Web Site , Application Service , Web Role 不管它曾經叫過什麼名字,講簡單一點它就是 Azure 上的 Hosting ,以前在地端的時候大家都會注意 Web.config 要加密才能丟到對外空間,為什麼到了雲端環境以後就沒人理了呢?

首先看一下在地端中我們習慣的 Web.config 加密方式

嗯.....Aspnet_regiis.exe 放在 Application Service 的網站怎麼找到它?

假設您找到它了,那要怎麼執行?真雲端環境隨時都可以依據需求一台、兩台、三台的在跑,你要怎麼去執行加密的動作?

越想越不可能的結果就是「算了,雲端是很安全的,我要是被盜了我就找微軟開刀就好了」這樣的心態開始萌生。

But! 敏感資訊不能加密那剛好我使用了 GitHub 做版控,不能加密的情況下不是就被人看光光了?

其實 Application Service 加密 Web.config 中的敏感字串一點都不難,說難聽點這件事情根本沒有技術含量,那為什麼很多人沒有做呢?我想是因為不知道,或是對於資安的敏感程度不夠吧。

為了讓更多人知道這件事情,我們就來寫篇文吧~


環境說明

  • 您必須要有一個合法的 Microsoft Azure 帳號。
  • 您必須建立一個 Application Service(應用程式服務)。
  • 您可以用 「F1 免費」層級練習,但如果是線上環境建議您至少提升到 「S1 標準」。(主要是需要多個部屬位置,不然一改錯就會造成網站停擺)
  • 以下範例會使用「F1 免費」層級。

 

模擬情境

假設我們現在有一個 demotc-826(production) 網站,並且已經將範例網站部屬上去了,範例網站就使用標準的 MVC5 範本,將範本的 Web.config 開啟可以看到連線字串赤裸裸的放在那

<connectionStrings>
  <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-demotc-826-20151227043258.mdf;Initial Catalog=aspnet-demotc-826-20151227043258;Integrated Security=True"
    providerName="System.Data.SqlClient" />
</connectionStrings>

然後我有一個第三方簡訊服務的 Token 於是就很自然的設定到 Appsetting 內

<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="SmsToken" value="31bf3856ad364e35" />
  </appSettings>

就這樣是不是覺得有點危險?雖然說放到 Application Service(應用程式服務)在預設的情況下不會被看到,但難保團隊出現天兵程式寫錯,或是有﹍一樣的隊友把專案放一份到 GitHub 準備回家繼續趕工。

為了示範方便,demo修改了首頁,讓連線字串與簡訊Token直接揭露在網站上

這樣的設定就是我們平常習慣的明碼儲存敏感資訊,再來就是調整了。

調整 Web.config

調整 AppSettings 內的 SmsToken 如下(就是 value 改用 ... 來取代)

<add key="SmsToken" value="..." />

 

再調整 ConnectionStrings 如下(就是 connectionString 改用 yoyoyo 來取代)

<add name="DefaultConnection" connectionString="yoyoyo" providerName="System.Data.SqlClient" />

再來看一次網頁的執行效果

Azure應用程式設定

OK!現在沒有人知道我們的敏感資料了,問題是這樣程式要怎麼跑呢?請前往 Azure 管理介面選擇「所有設定」→「應用程式設定」

 

AppSettings設定

在「應用程式設定」內新增SmsToken 並且將值設定為真正的 Token

見證奇蹟的時刻到了,將放置於 Azure 的範例網站按下重新整理

看出來了嗎?我們程式中的設定是「...」上傳到 Azure 也是「...」但只要利用 Azure Portal 設定好真正的值就會自動置換,而且隨時都可以調整立即生效,兼顧了安全與便利,魚與熊掌是可以兼得的。


 

連線字串設定

接下來就是設定 ConnectionStrings 的部分

必須注意「值」的部分是要將所有的 ConnectionStrings 都塞進去如下圖反白的部分

將放置於 Azure 的範例網站按下重新整理即可看到變化

連線字串設定-使用 EntityFramework 注意事項

如果您的連線字串是 EF 產生的,您要複製的依然是 connectionString 內的所有字串

但是你必須要將 &quot; 改為 " 如下:

metadata=res://*/Models.defaultModel.csdl|res://*/Models.defaultModel.ssdl|res://*/Models.defaultModel.msl;provider=System.Data.SqlClient;provider connection string="data source=192.168.0.1;initial catalog=defaultDb;User Id=test;Password=test;MultipleActiveResultSets=True;App=EntityFramework"

並且要將後方下拉選單改成「自訂」

如果連線字串設定或是應用程式設定只要有設定錯誤網站就會直接跳出 500 (請注意你這裡是在調整 Web.config的值)

 

使用預備環境避免手殘自爆

如果「連線字串設定」或是「應用程式設定」只要設定錯誤,網站就會直接跳出 500 因為其實你是在調整 Web.config 所以使用上不得不小心,要避免手殘導致線上網站自爆的最好方式就是將網站提升為「S1 標準」等級,這樣可以讓網站擁有預備位置,您可以在預備位置中嘗試調整相關設定值,調整完畢後再使用「交換」的功能換到正式環境。

如果在設定時您有將後方的「位置設定」打勾,那表示此設定會停留在此位置,不會因為交換而換過去,所以可以增加一個 Appsetting 來判斷現在是正式環境還是預備環境(不用再使用判斷網址的爛招了)

還有在做「交換」的時候請務必看清楚「警告」的訊息,您可能會誤將設定清空,觀念和比對資料庫資料或結構一樣,來源會比目的的設定高級,因此如果您是在「預備環境」將設定值設定好,也請務必在「預備環境」按下「交換」。

 

以上所介紹的是充分利用 Azure 功能來達成簡單的「識別」「資安」兩項需求, Azure 還有另一個服務可以將類似的設定玩得更出神入化,不過那就有空再來寫了.....

回應討論