更改数据库密码和避免网站停机的过程

时间:2017-06-16 23:36:23

标签: asp.net sql-server database security

老板说我们需要更频繁地更改我们的SQL Server帐户密码,而且根本不需要。昨天我们发现我们的一个web.config文件可能在一个多月前就已被泄露,他昨天决定这一点。它包含三个数据库的凭据,并且所有三个密码都是几年(根据密码中包含的年份来判断)。

因此,如果我有两个不同的DBA要处理,每个需要一个耗时的票证流程来更改密码,以及需要类似耗时过程的Web服务器管理器,似乎没有办法改变所有在我更新网站的web.config之前,没有大量停机时间的三个SQL Server帐户密码。他希望我们现在每三个月做一次。

因此,我向DBA建议,在此示例中,每个数据库应该有两个帐户,一个是活动的,一个是99%的时间都是禁用的。然后每3个月,对于每个数据库,我可以请求DBA启用备用帐户并为其提供新密码。然后我可以请求指向新帐户的web.config更新。网站更新后,DBA可以禁用不再使用的三个帐户。

这是一种常见做法吗?它有一个术语吗?有更好的主意吗?因为这个想法在这里得到了一些推迟。最后,为什么SQL Server(或任何类似的技术)可选择允许旧密码在短时间内生存,例如在更改帐户密码后的一小时,以帮助我们在这种情况下想避免停工?

感谢您走到这一步!

2 个答案:

答案 0 :(得分:1)

我最近通过以下顺序解决了这个问题。

  1. 将授予各个登录/用户的所有权限转换为基于角色的(详见下文)。
  2. 使用与第一个不同的密码创建第二个登录/用户(如您所建议的);将它们添加到该角色。
  3. 让您的申请过渡到第二次登录。
  4. 确认您没有看到首次登录的任何登录事件。
  5. 更改首次登录的密码(如果您希望保持安全表面积尽可能小,请将其完全删除)。
  6. 至于“创建角色并将权限转移到它”位,这是我使用的脚本:

    declare @user sysname = '<your user here>',
        @role sysname = '<your role here>';
    
    -- no changes should be necessary below here
    
    select concat('CREATE ROLE ', quotename(@role), ' AUTHORIZATION [dbo];') AS [grant], '' AS [revoke], '' AS [permission_name], NULL AS [class_desc]
    union all
    select concat('ALTER ROLE ', quotename(@role), ' ADD MEMBER ', QUOTENAME(@user), ';'), '', '', null
    UNION all
    select concat('GRANT ', permission_name collate database_default, ' ON ',
    
            CASE class_desc
                when 'OBJECT_OR_COLUMN' then 'OBJECT::'
                when 'TYPE' then 'TYPE::'
            END,
    
        QUOTENAME(
        CASE class_desc
                when 'OBJECT_OR_COLUMN' then OBJECT_SCHEMA_NAME(major_id)
                when 'TYPE' then (SELECT SCHEMA_NAME([schema_id]) FROM sys.[types] WHERE [user_type_id] = [major_id])
        END), '.',
    
        quotename(
            CASE class_desc
                when 'OBJECT_OR_COLUMN' then object_name(major_id)
                when 'TYPE' then TYPE_NAME(major_id)
            END
        ),
        ' TO ', QUOTENAME(@role), ';'
    ), 
    
    CONCAT('REVOKE ', permission_name collate database_default, ' ON ',
    
            CASE class_desc
                when 'OBJECT_OR_COLUMN' then 'OBJECT::'
                when 'TYPE' then 'TYPE::'
            END,
    
        QUOTENAME(
        CASE class_desc
                when 'OBJECT_OR_COLUMN' then OBJECT_SCHEMA_NAME(major_id)
                when 'TYPE' then (SELECT SCHEMA_NAME([schema_id]) FROM sys.[types] WHERE [user_type_id] = [major_id])
        END), '.',
    
        quotename(
            CASE class_desc
                when 'OBJECT_OR_COLUMN' then object_name(major_id)
                when 'TYPE' then TYPE_NAME(major_id)
            END
        ),
        ' FROM ', QUOTENAME(@user), ';'
    ), [permission_name], [class_desc]
    from sys.database_permissions
    where grantee_principal_id = user_id(@user)
        AND [permission_name] <> 'CONNECT'
    ORDER BY [permission_name];
    

    就我而言,我只需要担心对象和用户定义的类型权限;如果你有更多,你将不得不考虑他们。但是上面会生成一个包含四列的结果集。 grant列将是用于创建角色的SQL,将您指定的用户添加到角色,然后向角色授予用户当前具有的所有权限。 revoke列将是用于从用户那里获取相同权限的SQL。另外两列只是为了我的理智,因为我正在开发脚本以确保我没有错过任何东西。

    一旦您运行了以上所有内容(请在投入生产之前在非生产环境中进行测试!),您的应用程序将利用该角色获取 它的权限。在此之后,您应该能够自信地以适合您需要的节奏继续推进上述详细计划的其余部分。

答案 1 :(得分:0)

  

web.config文件可能在一个月前就已被泄露

这似乎是问题的根源,所以恕我直言,这是应该解决的主要问题(即使回收pwds完全有道理 - 相比之下,它的结果很低)。

建议employ encryption for sensitive web.config sections来减轻这种情况。

H个。