引言
互联网每隔一段时间就会爆出 【某程序猿在代码托管平台上传了公司机密配置信息,导致公司核心数据被黑客获取或修改】, 一茬又一茬背锅侠层出不穷。拯救自我
软件工程理论早以加粗字体给出 经典原则:Never store production passwords or other sensitive data in source code
头脑风暴
.Net Framework
原配置节 <configuration> <appSettings file="appsecrets.config"> <add key="FtpUserId" value="test_userid" /> <add key="FtpPwd" value="test-pwd"> </appSettings> </configuration>
外置配置文件 <?xml version="1.0" encoding="utf-8" ?> <appSettings> <add key="FtpUrl" value="sftp.rategain.com" /> <add key="FtpUserId" value="RateGain_M&C" /> <add key="FtpPwd" value="RateGain@123" /> <add key="RemotePath" value="/M&C/" /> <!--路径 /M&C/ 需要转义--> </appSettings>
var hostBuilder = WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, builder) => { builder.AddJsonFile($"appsettings.secrets.json", optional: true); if (context.HostingEnvironment.IsDevelopment()) { builder.AddUserSecrets<Startup>(true); } builder.AddEnvironmentVariables(); }) .UseStartup<Startup>();
据此思路,可将敏感信息交由其他组件托管,.NetCore开发者还有其他3种实践:
- 适用于Dev的Secrets manager tool 托管
ASP.NETCore 在开发环境下保存密钥的方式,总体思路是使用一个匿名GUID引用存储在系统文件夹下的同名配置Json。
- 适用于Azure云的 Azure Key Vault 托管
https://azure.microsoft.com/en-us/resources/samples/key-vault-dotnet-core-quickstart/
- 适用于General Deploy的环境变量托管
下面对环境变量方式分离敏感信息做进一步说明。
环境变量托管
环境变量能在进程创建时被导入/注入,因此可作为一种敏感信息分离的思路, 环境变量来自三个级别 :系统、用户、进程。
介绍几种修改环境变量的方式:
①Windows-CMD命令行: setx命令, 注意该方式设置的环境变量需要在新的CMD界面上才能验证生效。
②系统控制面板-我的电脑-属性-高级设置-环境变量
以上两种形式均为在ASP.NET Core进程启动时导入系统环境变量,
③在Visual Studio launchsettings.json设定进程启动时注入环境变量
{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:11761/", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "JumpServer": { "commandName": "Project", "launchBrowser": true, "applicationUrl": "http://localhost:5020", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "production" , "ASPNETCORE_URLS": "http://localhost:5020" } } } }
④在VScode launchsettings.json设定进程启动时注入环境变量
{ "version": "0.2.0", "configurations": [ { "name": ".NET Core Launch (web)", "type": "coreclr", "request": "launch", "preLaunchTask": "build", "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/TestApp.dll", "args": [], "cwd": "${workspaceRoot}", "stopAtEntry": false, "launchBrowser": { "enabled": true, "args": "${auto-detect-url}", "windows": { "command": "cmd.exe", "args": "/C start ${auto-detect-url}" }, "osx": { "command": "open" }, "linux": { "command": "xdg-open" } }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" }, "sourceFileMap": { "/Views": "${workspaceRoot}/Views" } } ] }
⑤ 在进程启动时通过命令行参数注入,这种方式严格来说并不属于环境变量方式,是一种参数配置。
public static IWebHost BuildWebHost(string[] args) { var webHostBuilder = WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, configBuilder) => { // 启用命令行参数配置 configBuilder.AddCommandLine(args)
.AddEnvironmentVariables(); if (hostingContext.HostingEnvironment.IsDevelopment()) configBuilder.AddUserSecrets<Startup>(true); }) .ConfigureLogging((hostingContext, logging) => { logging.AddAzureWebAppDiagnostics(); }) .UseStartup<Startup>(); return webHostBuilder.Build(); }
--------------
dotnet run --environment "development"
⑥ 若使用IIS托管AspNetCore,可在IIS的配置编辑器新增/重写环境变量
在.NetCore生产部署实践中,比较常用的方式是使用独立的appsettings.secrets.json或环境变量来分离敏感信息。
掌握这些,.Net程序猿应该就不会因为在git上传机密信息而背锅了。
~~~~~~~~~更多方式,欢迎大家留言补充。~~~~