9

In our production environment the Sql server has some generic accounts(sql server accounts) used by the applications to access sql server. Users themselves have windows login which are readonly or write depending on user. We want to add a restriction which would allow only those generic account(sql server accounts) connections which originate from production application servers. Users themselves can connect from non prod server so we cannot block the sql ports in prod for connections from non prod servers.

Do we have some industry wide solutions for this?

We can have some sort of filtering in firewall which would filter the connections. Database solution might be too slow if it queries an api for each connection.

Is there a cool way to prevent applications in uat environment with wrong config settings(prod settings) to connect to our production database

puneet
  • 769
  • 1
  • 9
  • 34
  • I would use firewall rules to prevent access from other machines. Alternatively if the generic accounts are AD accounts rather than SQL Server logins I would only allow those accounts to login to the given machines – Steve Ford Jul 24 '15 at 12:39

5 Answers5

2

As has been suggested, you can use dynamic management views to identify login and IP addresses during the logon coupled with a logon trigger to restrict non-prod apps from accessing prod databases. Before I did this (again, as others have suggested), I would consider alternatives using:

  • Firewall rules to prevent non-prod boxes from reaching prod boxes
  • Ensuring the prod password does not match a non-prod account (especially good for keeping prod passwords out of things like source control or developers who may not necessarily need prod access)

With that said, here's a database-driven solution that let's you control the restrictions through a table that can live anywhere you want on the server.

CREATE TABLE SampleDB.dbo.LoginRestrictions (
    RestrictionId INT NOT NULL PRIMARY KEY,
    LoginName VARCHAR(500) NOT NULL,
    IpAddress VARCHAR(50) NOT NULL,
    Notes VARCHAR(500) NULL
)

INSERT SampleDB.dbo.LoginRestrictions VALUES
    ('app1', '10.1.1.125', 'Deny app1 from QA'),
    ('app1', '10.1.1.%', 'Deny app1 from DEV') -- Notice '%' so you can match general subnets
    -- ... Any other rules

Then, you can create a logon trigger that if a user login (can be a SQL account s in these cases, but you can also use domain logins to restrict any domain accounts if you wish). Also notice that the trigger uses LIKE so you can leverage wildcards in the IP addresses in case you can match by subnets.

CREATE TRIGGER tg_Logon_Blocker
ON ALL SERVER FOR LOGON AS
BEGIN
    SET NOCOUNT ON

    -- Rollback if restricted
    IF EXISTS (
        SELECT *
        FROM SampleDB.dbo.LoginRestrictions R
            INNER JOIN sys.server_principals P
                ON P.name = R.LoginName
            INNER JOIN sys.dm_exec_connections c
                ON c.session_id = @@SPID
                    AND c.client_net_address LIKE R.IpAddress
        WHERE p.name = ORIGINAL_LOGIN()
        )
        ROLLBACK

END
GO
Jason W
  • 13,026
  • 3
  • 31
  • 62
1

you may apply one of the different solutions proposed in this so answer but imho you have to better define your requirements and the context first.

if you want to prevent these users access from 'other' hosts but allow other users to access freely from anywhere then you have to act at the database level because only the database knows who is trying to log on: a logon trigger is the choice.

if the database is devoted to supply information to these hosts only then you may act on the firewall (maybe a more performing solution, to be evaluated depending on load, number of connections, number of hosts, lots of other variables) and drop all connection started from unknown machines.

if your environment have no 'defined boundaries' (i mean that the db server is used by other hosts also, is not used by the application servers only) maybe the creation of a new, dedicated db server can be evaluated; this would allow to apply the firewall solution (the one I prefer).

Community
  • 1
  • 1
Paolo
  • 2,224
  • 1
  • 15
  • 19
1

You could potentially create a Logon Trigger to check the client_net_address field of sys.dm_exec_connections, but that would tightly couple the security to the network setup and that can easily be forgotten about. And if the IT group makes a change and doesn't know about this, the Logon Trigger might either let too much in or too little ;-).

A firewall might be slightly better in that at least all control of the network setup and access is maintained within the IT group. But this is most likely overly complicated, especially if there are other accounts that are valid to reach from QA and/or UAT to Production.

The setup that I have seen work well in this situation is to use environment-specific service accounts. So you would have DEV-App, QA-App, UAT-App, and Prod-App. This would allow you to control other aspects of network access (such as file shares, etc) more granularly between environments. And you should probably be doing this anyway because you would want to know if there was a misconfiguration and the Prod-App account was trying to connect to a DEV SQL Server or file share.

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
  • We are using different accounts in dev, uat and prod but in scenarios like database migration/upgrade the prod configuration is tested. In some cases a developer might inadvertently use the prod config, specifically in case some application is not developed right and might have an extra config. – puneet Jul 25 '15 at 05:33
  • @puneet I am not sure I understand what you are saying. By "migration" do you mean promoting code from Dev -> QA -> UAT -> Prod? What do you mean by an "extra" config? And what do configurations have to do with the service account used for IIS / ASP.NET? Your "generic accounts" are Windows Logins via Active Directory, right? – Solomon Rutzky Jul 25 '15 at 05:42
  • By migration I meant sql upgrade or moving the servers, etc. Generic accounts are sql logins used specifically by applications, all humans login via their windows account. Extra config can be there in applications and this results in applications in uat connect to prod if the prod usernames are used – puneet Jul 25 '15 at 06:51
  • I was telling the scenarios in which there is a risk of non prod applications connecting to prod db. – puneet Jul 25 '15 at 06:58
  • @puneet Why are you using SQL Server logins for the generic service accounts? Does the same app server need to connect as different SQL accounts? Why isn't the config for each environment a part of that environment? Such as values stored in a table, or a config file that can only be deployed to its specific environment? Why is it possible for a developer to specify or use a different environment's config? There might be ways to change how configurations are handled and in turn fix the more general issue since connecting to the wrong server can't be the only problem when using the wrong config. – Solomon Rutzky Jul 27 '15 at 22:32
1

How about this... Network Service Account

Amar
  • 303
  • 1
  • 3
  • 19
  • 1
    How does this answer the question? Isn't this a step backwards for the O.P. since they currently have a standard account on various machines for easier administration, and this is one account per machine, which means that every time they add a new web server, they have to update all SQL Servers for the new Login? – Solomon Rutzky Jul 24 '15 at 18:06
1

Sounds like Application Roles could be a good solution for this.

Basically you would set up some application roles with appropriate permissions for the apps in question, and allow appropriate users to make the initial DB connection, with no other privileges. I recommend Windows authentication via AD group for this.

Your apps would then call sp_setapprole immediately after connection, at which point the connection assumes the permission of the application role.

The big advantage of this is that it remains within the standard SQL Server security model.

Of course you would still need to take some care that your app configs are correct.

beercohol
  • 2,577
  • 13
  • 26