This past Wednesday evening, 11th Dec, I braved the snowy roads down from Montreal to Winooski (Burlington area) to join a very friendly crowd at MyWebGrocer and presented all I know about AlwaysOn for the Vermont Professional Association for SQL Server, run by Roman Rehak.
I shall be placing an AlwaysOn script shortly, once I have cleaned up the code - however for those who were there, Roman Rehak was provided with all the files to redistribute also.
If the presentation link is blocked for you, please try this one on LinkedIn's server http://www.linkedin.com/profile/view?id=2308075&trk=wvmp-profile (see right after summary).
Thanks again to Roman and especially My Web Grocer for sharing its amazing work space with us.
sql server optimisation, sql server database management, sql discussions, help, clusters, backups, expansion, usefull tools, mcitp certification, server management, meilleures pratiques sql server, best practices.disaster recovery, deployment management, mirroring best practices and high availability, database security best practices
Monday, December 16, 2013
Wednesday, December 11, 2013
SQL Server Installation Folder Setup Log and Command Line Install Information
The other morning I was commenting during our regular meetings amongst fellow DBAs on where to read up on installation issues, or for simple text validation of what components were added during an installation process. This is the folder I want to point out: \\rootDrive:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log
Every install action, whether an Add of a node, settings validation, repair, remove, uninstall appears in this folder, and as soon as you have installation issues, go right to the specific Detail.txt under the Log folder corresponding to the date and time an installation was executed. You will see that Summary.txt has very little information, which is self-evident by its name.
For those of you who have a solid state drive at home (desktop / laptop, etc), to become familiar with how SQL Server is installed, I recommend a download of the SQL 2012 Developer edition ISO and to familiarize oneself with the command line installation - and if we could compare total install times (it's ll in the logs, no need for the stop watch), versus a GUI install that would be cool :) to share.
Every install action, whether an Add of a node, settings validation, repair, remove, uninstall appears in this folder, and as soon as you have installation issues, go right to the specific Detail.txt under the Log folder corresponding to the date and time an installation was executed. You will see that Summary.txt has very little information, which is self-evident by its name.
For those of you who have a solid state drive at home (desktop / laptop, etc), to become familiar with how SQL Server is installed, I recommend a download of the SQL 2012 Developer edition ISO and to familiarize oneself with the command line installation - and if we could compare total install times (it's ll in the logs, no need for the stop watch), versus a GUI install that would be cool :) to share.
For those who are curious regarding command line installs, here are some installation examples. Note that now you can mount your ISO natively in Win 2012/Windows 8 and run this comment directly from the mounted drive letter. I have avoided the use of /QS below because I like to see the GUI install to validate the parameters for a second time, just to ensure the instance starts off on the right foot.
CMD line install and one for an non-clustered with Analysis Services:
setup.exe /ACTION="Install" /AGTSVCPASSWORD="19CharacterPassword" /ASSVCPASSWORD="19CharacterPassword" /SAPWD="19CharacterPassword" /SQLSVCPASSWORD="19CharacterPassword" /INDICATEPROGRESS="true" /ENU="True" /UpdateEnabled="TRUE" /UpdateSource="Drive:\FOLDERCONTAININGLatestUpdate" /FEATURES=SQLENGINE,REPLICATION,FULLTEXT,DQ,AS,RS /HELP="False" /INDICATEPROGRESS="TRUE" /X86="False" /INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server" /INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server" /INSTANCENAME="InstanceName" /INSTANCEID="InstanceName" /ERRORREPORTING="True" /INSTANCEDIR="C:\Program Files\Microsoft SQL Server" /AGTSVCACCOUNT="InstanceSpecificServiceAccountName" /ASSVCACCOUNT="InstanceSpecificServiceAccountName" /ASSVCSTARTUPTYPE="Automatic" /ASCOLLATION="Latin1_General_CI_AS" /ASDATADIR="DriveName:1\olapdb_InstanceName" /ASLOGDIR="DriveName:\olaplog_InstanceName" /ASBACKUPDIR="DriveName:\olapbakup_InstanceName" /ASTEMPDIR="DriveName:\\olaptmp_VInstanceName" /ASCONFIGDIR="DriveName:\OLAP\Config" /ASPROVIDERMSOLAP="1" /ASSYSADMINACCOUNTS="ListOfUsers" "ADDINSTANCESPECIFICCCOUNT" /ASSERVERMODE="MULTIDIMENSIONAL" /FILESTREAMLEVEL="0" /SQLCOLLATION="Latin1_General_CI_AS" /SQLSVCACCOUNT="InstanceSpecificServiceAccountName" /SQLSYSADMINACCOUNTS="InstanceSpecificServiceAccountName" "ADDINSTANCESPECIFICCCOUNT" /SECURITYMODE="SQL" /INSTALLSQLDATADIR="DriveName:\sqlsysdb_InstanceName" /SQLBACKUPDIR="DriveName:\sqlbakup_InstanceName" /SQLUSERDBDIR="DriveName:\mpdbs001\sqlappdb_InstanceName" /SQLUSERDBLOGDIR="DriveName:\sqlapplog_InstanceName" /SQLTEMPDBDIR="DriveName:\sqltmpdb_InstanceName" /RSSVCACCOUNT="NT Service\ReportServer$InstanceName" /RSSVCSTARTUPTYPE="Automatic" /FTSVCACCOUNT="NT Service\MSSQLFDLauncher$InstanceName"
And a command line instance Repair:
setup.exe /QS /ACTION="repair" /ENU="True" /INSTANCENAME="NAME" /ASSVCACCOUNT="19CharacterPassword" /ASSVCPASSWORD="19CharacterPassword" /SAPWD="19CharacterPassword" /SQLSVCPASSWORD="19CharacterPassword"
For the most part, the cluster installation is exactly the same as the standalone SQL Server installation with the exception of a few screens in the GUI, and I would not recommend a Failover Cluster installation from the CMD prompt since you miss all the steps of whether parameters are valid for installation - unless you run CMD without the /QS parameter, which means an attended installation launched from the command link. I find this is a faster way of feeding the GUI installation procedure, and validating as you go along that the parameters actually work within the installation procedure before clicking Next (or equivalent) on each step.
Adding a node, however, is straightforward unattended and a real time-saver, NB when you add a node, you must provide again the passwords for service accounts.
setup.exe /ACTION="AddNode" /AGTSVCPASSWORD="StrongPassword" /SQLSVCPASSWORD="StrongPassword" /INDICATEPROGRESS="true" /ENU="True" /UpdateEnabled="False" /UpdateSource="Drive:\FOLDERCONTAININGLatestUpdate" /HELP="False" /INDICATEPROGRESS="TRUE" /X86="False" /INSTANCENAME="InstanceName" /FAILOVERCLUSTERGROUP="ClusterRoleName" /FAILOVERCLUSTERIPADDRESSES="IPv4;159.208.196.63;Public;255.255.252.0" /FAILOVERCLUSTERNETWORKNAME="SQLVirtualClusterName" /CONFIRMIPDEPENDENCYCHANGE=1 /AGTSVCACCOUNT="domain\InstanceSpecificServiceAccount" /SQLSVCACCOUNT="domain\InstanceSpecificServiceAccount"
---this one is when you have to add AS also on the second node
CMD line install and one for an non-clustered with Analysis Services:
setup.exe /ACTION="Install" /AGTSVCPASSWORD="19CharacterPassword" /ASSVCPASSWORD="19CharacterPassword" /SAPWD="19CharacterPassword" /SQLSVCPASSWORD="19CharacterPassword" /INDICATEPROGRESS="true" /ENU="True" /UpdateEnabled="TRUE" /UpdateSource="Drive:\FOLDERCONTAININGLatestUpdate" /FEATURES=SQLENGINE,REPLICATION,FULLTEXT,DQ,AS,RS /HELP="False" /INDICATEPROGRESS="TRUE" /X86="False" /INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server" /INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server" /INSTANCENAME="InstanceName" /INSTANCEID="InstanceName" /ERRORREPORTING="True" /INSTANCEDIR="C:\Program Files\Microsoft SQL Server" /AGTSVCACCOUNT="InstanceSpecificServiceAccountName" /ASSVCACCOUNT="InstanceSpecificServiceAccountName" /ASSVCSTARTUPTYPE="Automatic" /ASCOLLATION="Latin1_General_CI_AS" /ASDATADIR="DriveName:1\olapdb_InstanceName" /ASLOGDIR="DriveName:\olaplog_InstanceName" /ASBACKUPDIR="DriveName:\olapbakup_InstanceName" /ASTEMPDIR="DriveName:\\olaptmp_VInstanceName" /ASCONFIGDIR="DriveName:\OLAP\Config" /ASPROVIDERMSOLAP="1" /ASSYSADMINACCOUNTS="ListOfUsers" "ADDINSTANCESPECIFICCCOUNT" /ASSERVERMODE="MULTIDIMENSIONAL" /FILESTREAMLEVEL="0" /SQLCOLLATION="Latin1_General_CI_AS" /SQLSVCACCOUNT="InstanceSpecificServiceAccountName" /SQLSYSADMINACCOUNTS="InstanceSpecificServiceAccountName" "ADDINSTANCESPECIFICCCOUNT" /SECURITYMODE="SQL" /INSTALLSQLDATADIR="DriveName:\sqlsysdb_InstanceName" /SQLBACKUPDIR="DriveName:\sqlbakup_InstanceName" /SQLUSERDBDIR="DriveName:\mpdbs001\sqlappdb_InstanceName" /SQLUSERDBLOGDIR="DriveName:\sqlapplog_InstanceName" /SQLTEMPDBDIR="DriveName:\sqltmpdb_InstanceName" /RSSVCACCOUNT="NT Service\ReportServer$InstanceName" /RSSVCSTARTUPTYPE="Automatic" /FTSVCACCOUNT="NT Service\MSSQLFDLauncher$InstanceName"
And a command line instance Repair:
setup.exe /QS /ACTION="repair" /ENU="True" /INSTANCENAME="NAME" /ASSVCACCOUNT="19CharacterPassword" /ASSVCPASSWORD="19CharacterPassword" /SAPWD="19CharacterPassword" /SQLSVCPASSWORD="19CharacterPassword"
For the most part, the cluster installation is exactly the same as the standalone SQL Server installation with the exception of a few screens in the GUI, and I would not recommend a Failover Cluster installation from the CMD prompt since you miss all the steps of whether parameters are valid for installation - unless you run CMD without the /QS parameter, which means an attended installation launched from the command link. I find this is a faster way of feeding the GUI installation procedure, and validating as you go along that the parameters actually work within the installation procedure before clicking Next (or equivalent) on each step.
Adding a node, however, is straightforward unattended and a real time-saver, NB when you add a node, you must provide again the passwords for service accounts.
setup.exe /ACTION="AddNode" /AGTSVCPASSWORD="StrongPassword" /SQLSVCPASSWORD="StrongPassword" /INDICATEPROGRESS="true" /ENU="True" /UpdateEnabled="False" /UpdateSource="Drive:\FOLDERCONTAININGLatestUpdate" /HELP="False" /INDICATEPROGRESS="TRUE" /X86="False" /INSTANCENAME="InstanceName" /FAILOVERCLUSTERGROUP="ClusterRoleName" /FAILOVERCLUSTERIPADDRESSES="IPv4;159.208.196.63;Public;255.255.252.0" /FAILOVERCLUSTERNETWORKNAME="SQLVirtualClusterName" /CONFIRMIPDEPENDENCYCHANGE=1 /AGTSVCACCOUNT="domain\InstanceSpecificServiceAccount" /SQLSVCACCOUNT="domain\InstanceSpecificServiceAccount"
---this one is when you have to add AS also on the second node
setup.exe /ACTION="AddNode" /AGTSVCPASSWORD="StrongPassword" /SQLSVCPASSWORD="StrongPassword" /INDICATEPROGRESS="true" /ENU="True" /UpdateEnabled="False" /UpdateSource="MU" /HELP="False" /INDICATEPROGRESS="TRUE" /X86="False" /INSTANCENAME="InstanceName" /FAILOVERCLUSTERGROUP="ClusterRoleName" /FAILOVERCLUSTERIPADDRESSES="IPv4;IPADDRESSFORSQLVIRTUALSEVER;Public;255.255.252.0" /FAILOVERCLUSTERNETWORKNAME="DNSVirtualServerEntry" /CONFIRMIPDEPENDENCYCHANGE=1 /AGTSVCACCOUNT="domain\InstanceAccountName" /SQLSVCACCOUNT="domain\InstanceAccountName" /ASSVCACCOUNT="domain\user" /ASSVCPASSWORD="StrongPassword"
Using a Configuration file to add a second node to a cluster:
setup.exe /qs /ACTION="AddNode" /CONFIGURATIONFILE=”DRIVEONOTHERNODE:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\ConfigurationFileINSTANCENAME.ini” /AGTSVCPASSWORD=”15CharacterPassword" /ASSVCPASSWORD=”15CharacterPassword" /SQLSVCPASSWORD=”15CharacterPassword" /INDICATEPROGRESS="TRUE"
Changing Database Server Collation:, err, if you set it wrong by accident (works exclusively for standalone from my experience):
Setup /QS /ACTION=REBUILDDATABASE /INSTANCENAME="InstanceName" /INDICATEPROGRESS="TRUE" /SQLSYSADMINACCOUNTS="ML\oth_mlsqldbms" "listOfAccounts" "domain\userGroup" /SAPWD="StrongPassword" /SQLCOLLATION=SQL_Latin1_General_CP1_CI_AS
References (for all the other options):
http://msdn.microsoft.com/en-us/library/ms144259.aspx
Using a Configuration file to add a second node to a cluster:
setup.exe /qs /ACTION="AddNode" /CONFIGURATIONFILE=”DRIVEONOTHERNODE:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\ConfigurationFileINSTANCENAME.ini” /AGTSVCPASSWORD=”15CharacterPassword" /ASSVCPASSWORD=”15CharacterPassword" /SQLSVCPASSWORD=”15CharacterPassword" /INDICATEPROGRESS="TRUE"
Changing Database Server Collation:, err, if you set it wrong by accident (works exclusively for standalone from my experience):
Setup /QS /ACTION=REBUILDDATABASE /INSTANCENAME="InstanceName" /INDICATEPROGRESS="TRUE" /SQLSYSADMINACCOUNTS="ML\oth_mlsqldbms" "listOfAccounts" "domain\userGroup" /SAPWD="StrongPassword" /SQLCOLLATION=SQL_Latin1_General_CP1_CI_AS
References (for all the other options):
http://msdn.microsoft.com/en-us/library/ms144259.aspx
Wednesday, October 09, 2013
Leveraging LinkedIn to Contribute to the DBA Community & Attract Opportunities with Internationally-Oriented Organisations
LinkedIn has matured over the past decade and I can
sincerely say it is well worth the time setting up your profile and actually
completing it. It is pretty much the
ultimate business networking tool-until replaced by a competitor of course! Much
of facebooks’ features have been mimicked into the site also, which helps
evaluate shared topic interests.
The prerequisite to fully take advantage of
LinkedIn, would be completing one’s profile to the 100% level and obtaining as
many recommendations as possible, although now with Endorsements (from LinkedIn contacts) the written recommendations
have been fully taken over by the latter. Pre-MVP award, I had made
efforts to request recommendations, or exchange them, to grow over the ten
person threshold, since, at the time, I
believed establishing credibility by means of online references is a
significant prerequisite to mastering LinkedIn’s networking potential. If you
recommend someone online, they are taking a leap of faith in you; since it is
something they are willing to state in front of the entire world basically how
that individual feels about your workplace conduct (i.e. playing nice in the
sandbox). However, once the option of endorsements for specific skills became
available, the ease of it simply opened the flood to hundreds of endorsements
(if you are publicly contributing by blogs or writing, this has been my
experience, at least, as you can see below).
LinkedIn endorsements, accumulated after five years of blogging, writing, speaking, etc. |
You’ll be pleasantly surprised also, that if you
describe the way you prefer to work exactly (e.g. personally, I described
following Brad McGehee’s Exceptional DBA guide), or the methodology you follow, it
will allow you to bring in qualified clients/opportunities and provide the
chance to filter out unwanted mandates. My current job in Montreal was found through
recruitment agencies working ironically, in another province, although my current and former colleagues play hockey together!
LinkedIn also provides opportunities for diversity of work, which contributes to experience on a whole, proves invaluable and maintains the profession of being a DBA across platforms (or DBA polyglot as I have pushed), even if only minimal tasks executed over a few days here and there accumulate into a personal body of knowledge which bloggers can benefit from themselves, as well as the contribution to community. Inside organisations, I encourage DBAs to post blogs to demystify our profession and approach, as well as help educate Developers and elude some pretty foul code.
LinkedIn also provides opportunities for diversity of work, which contributes to experience on a whole, proves invaluable and maintains the profession of being a DBA across platforms (or DBA polyglot as I have pushed), even if only minimal tasks executed over a few days here and there accumulate into a personal body of knowledge which bloggers can benefit from themselves, as well as the contribution to community. Inside organisations, I encourage DBAs to post blogs to demystify our profession and approach, as well as help educate Developers and elude some pretty foul code.
Further, it should be treated as a longer than
usual Curriculum Vitæ or Résumé in North America (unless you are in MX, or the province of QC) but in accordance to the format
obviously, because perhaps if you place details in the wrong portion of your
profile, an opportunity could easily be missed. I love the way a
mate here in Montreal (Martin Arvisais) describes it as a great place ‘pour vendre ta
salade’ (cute local way of saying to sell your stuff in French). Now you can
upload word documents to your LinkedIn profile directly for those who would
like to see the traditional format.
The other improvement, although not that recent, is that LinkedIn is much like a blog platform too, since you can share almost anything. It is method to make a pillar of the all-important (in this net-oriented generation), Online Persona.
The other improvement, although not that recent, is that LinkedIn is much like a blog platform too, since you can share almost anything. It is method to make a pillar of the all-important (in this net-oriented generation), Online Persona.
Another good reason to do it is, to be quite
forthright, showing how you can contribute to your professional community, and
thus leveraging your contacts within this tool. There are several
SQL Server related groups in LinkedIn, my contributions through the
LinkedIn groups are part of the reason why Canada’s MVP Lead approached me back
in 2009 for a nomination (also, thanks to a referral from SQLServerToolBox.com‘s Scott Stauffer, and
frequent speaker, a SQL DBA based in Vancouver) – therefore, what more
motivation could one implore to Link themselves In.
Friday, September 13, 2013
How to Avoid the 'Abuse' of SysAdmin by Applying User Defined Roles in SQL 2012 (and keep Exec.s and Auditors Happy)
This will not be a typical post, just a dive right away into Data Access Language Code, which provides a method to avoid the SysAdmin fixed Server role in SQL Server for DBAs and Monitoring/Auditing Accounts, thanks to extensive explicit permissions and taking full advantage of SQL 2012-4 User Define Server Roles or Flexible Server Roles.
CREATE LOGIN [SeniorSQLDBA1] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
CREATE USER [DBAGroup1] FOR LOGIN [DBAGroup1]
use master
go
exec sp_helpsrvrolemember 'sysadmin'
-- reduce members to bare minimum !!
-- for each new application added, one should verify the wanted/identifiable
-- (and not unwanted) logins are viewed
select * from sys.dm_exec_connections
--final review of permissions
SELECT * FROM sys.fn_builtin_permissions('SERVER')
ORDER BY permission_name;
-- again but at a different level
SELECT * FROM sys.fn_builtin_permissions('default')
ORDER BY permission_name;
-- database securable
SELECT * FROM sys.fn_builtin_permissions('database')
ORDER BY permission_name;
-- This script
would be a required step to do post instance install and to apply flexible
server roles
-- We are to
apply this as a security policy in production environments, and then perform
validation
-- Could be
applied on some Dev/UAT servers
-- start with a rollback / back-out - or clean
out roles to start again (alternatively skip to line 50)
USE [master]
GO
Drop Server Role DBAs;
Drop Server Role Monitoring;
go
-- Add DBAs
back to fixed server role sysadmin, unless on servers
that will not be managed by DBAs
ALTER SERVER ROLE [sysadmin] ADD MEMBER [Group1]
ALTER SERVER ROLE [sysadmin] ADD MEMBER [MonitoringAccount1]
ALTER SERVER ROLE [sysadmin] ADD MEMBER [MonitoringAccount2]
ALTER SERVER ROLE [sysadmin] ADD MEMBER [AuditingAccount]
GO
-- drop
explicit rights in master, model and msdb also
USE [msdb]
GO
ALTER ROLE [ServerGroupAdministratorRole]
DROP MEMBER [DBAGroup2]
ALTER ROLE [ServerGroupAdministratorRole]
DROP MEMBER [DBAGroup1]
GO
ALTER ROLE [SQLAgentOperatorRole]
DROP MEMBER [DBAGroup2]
ALTER ROLE [SQLAgentOperatorRole]
DROP MEMBER [DBAGroup1]
GO-- not supposed to exist, but just in case
ALTER ROLE [db_owner]
DROP MEMBER [DBAGroup2]
ALTER ROLE [db_owner]
DROP MEMBER [DBAGroup1]
GO
use model
go
GRANT select, insert, TAKE OWNERSHIP, view definition, update, execute, CONTROL, REFERENCES
on schema::dbo to [DBAGroup2]
GRANT select, insert, TAKE OWNERSHIP, view definition, update, execute, CONTROL, REFERENCES
ON SCHEMA::[dbo]
TO [DBAGroup1]
GO -- don't forget you can easily enough do DENY permissions too to prevent data modificación
use master
go
-- All
sections of this Security Hardening should correspond to a master Document/ed procedure
ALTER LOGIN [sa] enable
GO
use [Master]
go
drop USER [AuditingAccount] FOR LOGIN [AuditingAccount]
drop USER [MonitoringAccount1] FOR
LOGIN [MonitoringAccount1]
drop USER [MonitoringAccount2] FOR
LOGIN [MonitoringAccount2]
--- END CLEAN
UP / Rollback of Role Security hardening
-- BEGIN SQL Security Hardening
--- disable SA, but do not drop it, maybe needed for service
packs or for backout in Startup
-m option (single-user mode)
ALTER LOGIN [sa] disable -- ALTER LOGIN [sa]
enable
GO
-- before applying any security policy, ensure
BUILTIN\Administrators not there
USE MASTER
GO
GO
IF EXISTS (SELECT * FROM sys.server_principals
WHERE name = N’BUILTIN\Administrators’)
DROP LOGIN [BUILTIN\Administrators]
GO
-- New in SQL 2012 - User Defined Server Roles, begin to take
advantage of them
-- using roles
rather than granting access to individuals, is a best practice in itself,
-- and the flexibility of user defined roles has become essential for many reasons
-- not limited to but including auditing, compliance, best management practices
-- and the flexibility of user defined roles has become essential for many reasons
-- not limited to but including auditing, compliance, best management practices
Create Server Role DBAs Authorization [securityadmin];
-- where SecurityAdmin contains just
a few who have FireCall IDs (elevated accounts, for
rare use)
-- example with a few DBAs
IF NOT EXISTS (SELECT * FROM sys.server_principals
WHERE name = N’SeniorSQLDBA1’)CREATE LOGIN [SeniorSQLDBA1] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
IF NOT EXISTS (SELECT * FROM sys.server_principals
WHERE name = N’SeniorSQLDBA2’)
CREATE LOGIN [SeniorSQLDBA2]
FROM WINDOWS WITH DEFAULT_DATABASE=[master]
go
-- add a few
senior dbas to [securityadmin]
only for now (unless Super User/System Admin account exists)
ALTER SERVER ROLE [securityadmin] ADD MEMBER [SeniorSQLDBA2]
ALTER SERVER ROLE [securityadmin] ADD MEMBER [SeniorSQLDBA1]
-- these senior dbas should backup
each other in case of role issues and revised grants have to be applied
GO
IF NOT EXISTS (SELECT * FROM sys.server_principals
WHERE name = N’DBAGroup1’)
CREATE LOGIN [DBAGroup1] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
IF NOT EXISTS (SELECT * FROM sys.server_principals
WHERE name = N’DBAGroup2’)
CREATE LOGIN [DBAGroup2] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
CREATE USER [DBAGroup1] FOR LOGIN [DBAGroup1]
CREATE USER [DBAGroup2] FOR LOGIN [DBAGroup2]
GO
-- add DBA
groups to the role
Alter server role DBAs add member [DBAGroup2]
-- we could use a subset of the following grants for different
'levels' of DBAs
-- (i.e. a JuniorDBA flexible server role)
-- (i.e. a JuniorDBA flexible server role)
Alter server role DBAs add member [DBAGroup1]
-- now lock down for operations we as DBAs should not be doing
anyway
-- do not
forget to give WITH GRANT rights when necessary
-- (please
validate in the GUI afterwards that DBAs role has the correct DAL)
-- (all
necessary permissions to do DBA job, minus unnecessary privileges)
GRANT ADMINISTER BULK OPERATIONS TO [DBAs] WITH GRANT OPTION
GRANT ALTER ANY CONNECTION TO [DBAs] WITH GRANT OPTION
GRANT ALTER ANY CREDENTIAL TO [DBAs] WITH GRANT OPTION
GRANT ALTER ANY DATABASE TO [DBAs] WITH GRANT OPTION
GRANT Shutdown to DBAs
GRANT control server TO [DBAs]
-- Luckily
Control Server permission respects the following DENYs
-- which is not the case for sysadmin fixed role
-- which is not the case for sysadmin fixed role
GRANT ALTER ANY EVENT NOTIFICATION TO [DBAs] WITH GRANT OPTION
GRANT ALTER ANY EVENT SESSION TO [DBAs] WITH GRANT OPTION
GRANT ALTER RESOURCES TO [DBAs]
GRANT ALTER SERVER STATE TO [DBAs]
GRANT ALTER SETTINGS TO [DBAs]
GRANT AUTHENTICATE SERVER TO [DBAs]
-- Grants or
denies the ability to use a particular signature across all databases on the
server
-- when impersonation is used.
-- when impersonation is used.
GRANT CONNECT SQL TO [DBAs] WITH GRANT OPTION
-- Grants or
denies the ability to connect to the SQL Server.
-- All logins,
when newly created, are granted this permission automatically
GRANT CREATE ANY DATABASE TO [DBAs] WITH GRANT OPTION
-- GRANT
CREATE AVAILABILITY GROUP TO [DBAs] (if you have Av. Groups at all)
GRANT CREATE DDL EVENT NOTIFICATION TO [DBAs]
GRANT CREATE TRACE EVENT NOTIFICATION TO [DBAs]
GRANT VIEW ANY DATABASE TO [DBAs] WITH GRANT OPTION
GRANT VIEW ANY DEFINITION TO [DBAs]
GRANT VIEW SERVER STATE TO [DBAs]
GRANT ALTER ANY EVENT NOTIFICATION TO [DBAs]
GRANT ALTER ANY EVENT SESSION TO [DBAs]
GRANT ALTER ANY LOGIN TO [DBAs] -- some may want this as a DENY
--- Now the explicit denys (options)
DENY ALTER ANY AVAILABILITY GROUP TO [DBAs]
DENY ALTER ANY ENDPOINT TO [DBAs]
DENY ALTER ANY LINKED SERVER TO [DBAs]
-- debatable regarding linked servers
DENY ALTER ANY SERVER ROLE TO [DBAs]
--obviously,
we want control on number or roles
DENY ALTER TRACE TO [DBAs]
DENY CREATE ENDPOINT TO [DBAs]
Deny impersonate on login::sa to
DBAs
-- add any
other accounts that are individual users on the server with elevated rights,
-- and the Service Account(s)
Deny impersonate on login::[SERVICEaccountNameHere] to [DBAs]
-- and the Service Account(s)
Deny impersonate on login::[SERVICEaccountNameHere] to [DBAs]
Deny Alter any Server Audit to DBAs
Deny Unsafe Assembly to DBAs;
GO
-- resolve
master grants
USE [master]
GO
GRANT select, view definition, execute, CONTROL, REFERENCES on schema::dbo
to [DBAGroup2]
GRANT select, view definition, execute on schema::sys to [DBAGroup2]
GRANT EXECUTE ON xp_readerrorlog TO [DBAGroup2] -- helpful to get DBAs to query the error log
GRANT EXECUTE ON sp_readerrorlog TO [DBAGroup2]
ALTER ROLE [db_datareader]
ADD MEMBER [DBAGroup2]
GO
GRANT select, view definition, execute, CONTROL, REFERENCES on schema::dbo
to [DBAGroup1]
GRANT select, view definition, execute on schema::sys to [DBAGroup1]
GRANT EXECUTE ON xp_readerrorlog TO [DBAGroup1]
GRANT EXECUTE ON sp_readerrorlog TO [DBAGroup1]
ALTER ROLE [db_datareader]
ADD MEMBER [DBAGroup1]
GO
-- resolve
MSDB grants
USE [msdb]
GO
CREATE USER [DBAGroup1] FOR LOGIN [DBAGroup1]
CREATE USER [DBAGroup2] FOR LOGIN [DBAGroup2]
go
ALTER ROLE [ServerGroupAdministratorRole]
ADD MEMBER [DBAGroup1]
ALTER ROLE SQLAgentOperatorRole
ADD MEMBER [DBAGroup1]
GO
ALTER ROLE [ServerGroupAdministratorRole]
ADD MEMBER [DBAGroup2]
ALTER ROLE SQLAgentOperatorRole
ADD MEMBER [DBAGroup2]
GO -- after roles, grant explicit rights to be sure nothing is
missing
GRANT select, execute, CONTROL, REFERENCES on schema::dbo to [DBAGroup2]
GO
GRANT select, execute, CONTROL, REFERENCES on schema::dbo ON SCHEMA::[dbo]
TO [DBAGroup1]
GO -- allow DBAs to be part of msdb
ownership if you like
--ALTER ROLE [db_owner] ADD MEMBER [DBAGroup1]
GO -- not necessary since in above Admnistrator
and Operator roles
ALTER ROLE [db_ssisadmin] ADD MEMBER [DBAGroup2]
go
-- resolve issues for all new databases created - fix MODEL
database to include DBAs.
Use Model
GO
-- setup DenyData reader role by
default for groups to cover Prod data constraint
CREATE USER [DBAGroup1] FOR LOGIN [DBAGroup1]
CREATE USER [DBAGroup2] FOR LOGIN [DBAGroup2]
-- all user databases for production, will have deny read on
the data
GO
-- use roles
even at the database level
CREATE ROLE [DBAs] AUTHORIZATION [dbo]
GRANT VIEW DATABASE State, execute, view definition TO [DBAs]
-- remove read
access when necessary, but allow administration
-- add
appropriate groups
ALTER ROLE [DBAs] ADD MEMBER [DBAGroup2]
ALTER ROLE [DBAs] ADD MEMBER [DBAGroup1]
-- and finally, requirements for some prod. environments
Deny select, insert, update TO [DBAs]
GO
-- or deny select in prod user dbs
this way
ALTER ROLE [db_denydatareader]
ADD MEMBER [DBAGroup2]
ALTER ROLE [db_denydatareader]
ADD MEMBER [DBAGroup1]
GO
-- WE DO NOT STOP THERE,
CONTINUE with Monitoring Accounts
-- which traditionally have way too many Privileges
-- which traditionally have way too many Privileges
-- and the goal is to adhere to the principle of least
privileges
use master
GO
-- create
monitoring role and add accounts the monitor the servers
Create Server Role [Monitoring] Authorization
[securityadmin];
-- the right logins in the container
CREATE LOGIN [MonitoringAccount1]
FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
CREATE LOGIN [MonitoringAccount2]
FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
CREATE LOGIN [AuditingAccount]
FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
ALTER SERVER ROLE [Monitoring] ADD MEMBER [MonitoringAccount1]
ALTER SERVER ROLE [Monitoring] ADD MEMBER [MonitoringAccount2]
ALTER SERVER ROLE [Monitoring] ADD MEMBER [AuditingAccount]
-- minimum WMI permissions required, so add to local admins on
the server too
GRANT CONNECT SQL TO [Monitoring]
GRANT CONTROL Server TO [Monitoring]
GRANT ALTER TRACE TO [Monitoring]
GRANT VIEW ANY DATABASE TO [Monitoring]
GRANT VIEW ANY DEFINITION TO [Monitoring]
GRANT VIEW SERVER STATE TO [Monitoring]
Grant CREATE DDL EVENT NOTIFICATION TO [Monitoring]
GRANT CREATE TRACE EVENT NOTIFICATION TO [Monitoring]
-- because we have granted control server, we must apply these
DENY statements
DENY ALTER ANY AVAILABILITY GROUP TO [Monitoring]
DENY ALTER ANY ENDPOINT TO [Monitoring]
DENY ALTER ANY LINKED SERVER TO [Monitoring]
DENY ALTER ANY LOGIN TO [Monitoring]
DENY ALTER ANY SERVER ROLE TO [Monitoring]
--obviously,
we want control on number or roles
DENY CREATE ENDPOINT TO [Monitoring]
Deny impersonate on login::sa to
[Monitoring]
-- add any
other accounts that are individual users on the server that have Sysadmin rights
Deny impersonate on login::[SERVICEaccountNameHere] to [Monitoring]
Deny impersonate on login::[SERVICEaccountNameHere] to [Monitoring]
Deny Alter any Server Audit to [Monitoring]
Deny Unsafe Assembly to [Monitoring];
-- Monitoring users need to be in Master and
Model, MSDB as DataReader
Go
CREATE USER [MonitoringAccount1] FOR LOGIN [MonitoringAccount1]
CREATE USER [MonitoringAccount1] FOR LOGIN [MonitoringAccount1]
CREATE USER [MonitoringAccount2]
FOR LOGIN [MonitoringAccount2]
CREATE USER [AuditingAccount]
FOR LOGIN [AuditingAccount]
--
ALTER ROLE [db_datareader]
ADD MEMBER [MonitoringAccount1]
ALTER ROLE [db_datareader]
ADD MEMBER [MonitoringAccount2]
ALTER ROLE [db_datareader]
ADD MEMBER [AuditingAccount]
-- or
more explicitly
grant select, view definition, execute on schema::dbo to [AuditingAccount]
grant select, view definition, execute on schema::dbo to [AuditingAccount]
grant select, view definition, execute on schema::sys to [AuditingAccount]
GRANT EXECUTE ON xp_readerrorlog TO [AuditingAccount]
GRANT EXECUTE ON sp_readerrorlog TO [AuditingAccount]
GO
grant select, view definition, execute on schema::dbo to [MonitoringAccount1]
grant select, view definition, execute on schema::dbo to [MonitoringAccount1]
grant select, view definition, execute on schema::sys to [MonitoringAccount1]
GRANT EXECUTE ON xp_readerrorlog TO [MonitoringAccount1]
GRANT EXECUTE ON sp_readerrorlog TO [MonitoringAccount1]
GO
grant select, view definition, execute on schema::dbo to [MonitoringAccount2]
grant select, view definition, execute on schema::sys to [MonitoringAccount2]
GRANT EXECUTE ON xp_readerrorlog TO [MonitoringAccount2]
GRANT EXECUTE ON sp_readerrorlog TO [MonitoringAccount2]
GO
USE [msdb]
USE [msdb]
GO -- the options here for system databases are to either
continue to create user defined roles, or used fixed if possible
CREATE USER [MonitoringAccount1]
FOR LOGIN [MonitoringAccount1]
CREATE USER [MonitoringAccount2]
FOR LOGIN [MonitoringAccount2]
CREATE USER [AuditingAccount]
FOR LOGIN [AuditingAccount]
GO
grant execute on schema::dbo to [MonitoringAccount1]
grant execute on schema::dbo to [MonitoringAccount2]
grant execute on schema::dbo to [AuditingAccount]
grant execute on schema::dbo to [MonitoringAccount1]
grant execute on schema::dbo to [MonitoringAccount2]
grant execute on schema::dbo to [AuditingAccount]
GO
-- improve
this by adding appropriate role?
ALTER ROLE [db_datareader]
ADD MEMBER [AuditingAccount] -- may need to use more elevate fixed roles here
ALTER ROLE [db_datareader]
ADD MEMBER [MonitoringAccount1]
ALTER ROLE [db_datareader]
ADD MEMBER [MonitoringAccount2]
GO
-- add model
for defaults similar DBA groups
Use Model
GO
CREATE USER [AuditingAccount]
FOR LOGIN [AuditingAccount]
CREATE USER [MonitoringAccount1]
FOR LOGIN [MonitoringAccount1]
CREATE USER [MonitoringAccount2]
FOR LOGIN [MonitoringAccount12]
-- all user databases for production, will have deny read on
the data
GO -- create monitoring database role
CREATE ROLE [Monitoring] AUTHORIZATION [dbo]
GRANT VIEW DATABASE State, execute, view definition TO [Monitoring]
-- remove read
access when necessary, but allow administration
Deny select, insert, update TO [Monitoring] -- requirements for some prod. environments
-- add
appropriate groups or accounts for auditing or monitoring
ALTER ROLE [Monitoring] ADD MEMBER [AuditingAccount]
ALTER ROLE [Monitoring] ADD MEMBER [MonitoringAccount1]
ALTER ROLE [Monitoring] ADD MEMBER [MonitoringAccount1]
GO
USE [master]
GO
-- cleanup those who were in sysadmin
ALTER SERVER ROLE [sysadmin] DROP MEMBER [DBAGroup2]
ALTER SERVER ROLE [sysadmin] DROP MEMBER [DBAGroup1]
ALTER SERVER ROLE [sysadmin] DROP MEMBER [AuditingAccount]
ALTER SERVER ROLE [sysadmin] DROP MEMBER [MonitoringAccount1]
-- you can truly state that you have reduced the SysAdmin elevate account access to your auditors
GO
-- validate that only those who you want are noe in sysadmin
-- validate that only those who you want are noe in sysadmin
use master
go
exec sp_helpsrvrolemember 'sysadmin'
-- reduce members to bare minimum !!
-- new for sql 2012: check which services are listed:
select * from sys.dm_server_services
-- for each new application added, one should verify the wanted/identifiable
-- (and not unwanted) logins are viewed
select * from sys.dm_exec_connections
--final review of permissions
SELECT * FROM sys.fn_builtin_permissions('SERVER')
ORDER BY permission_name;
-- again but at a different level
SELECT * FROM sys.fn_builtin_permissions('default')
ORDER BY permission_name;
-- database securable
SELECT * FROM sys.fn_builtin_permissions('database')
ORDER BY permission_name;
Subscribe to:
Posts (Atom)