Make Azure Firewall Rules Automatically Expire - sql-server

Caveat: Ok, so this might not be necessary, but my standard security mentality is to make things as hard as possible, and then ease up as required.
Right now, I'm the sole developer for a software system that is based in Azure (SQL Server and Mobile Service).
Although the entire system is designed to access its SQL Server databases using the Azure Mobile Service API, I'm using SSMS to administer the database during development and testing, and I've had to create a Firewall rule to allow this access. If this project expands (which looks likely in the next few months), I'll need to give other DB admins/developers access to some of the same resources. That's fine, but given the sensitive nature of some of the data we will be housing, I'd like to automatically invalidate those Azure SQL Server firewall rules at the end of the day. I realize that this will require their re-creation at the start of each business day. I am ok with this.
From what I've read, there appear to be 3 different ways to manage Azure SQL Server firewall rules programmatically:
T-SQL (sp_delete_firewall_rule)
REST API (DELETE to https://management.core...)
Azure Powershell (Remove-AzureSqlDatabaseServerFirewallRule)
I don't really care how it gets done, but I'm already using a Mobile Service Scheduler job to expire password reset tokens (totally unrelated to the current task), so I thought I would give that technique a shot.
Here was that attempt:
function ClearSqlServerFirewalls() {
var sql = 'Exec sp_delete_firewall_rule ?';
mssql.query(sql, ['name'], {
success: function (results) {
console.log(results);
}
});
}
In a not-terribly-surprising outcome, I got the following error:
User must be in the master database.
Ok, so that makes good sense, given that this is a system-wide effect, not a database-specific one. Azure apparently creates a specific SQL user for each database and runs all Mobile Service code through that user. Since that user doesn't have database-wide access, no dice.
So, here are my current thoughts on this:
SQL Agent apparently doesn't exist for SQL Azure, so automating the T-SQL script from within SQL Server appears to be out.
I don't yet know of a way to automate the REST API call from within Azure itself.
I am not familiar with Powershell in Azure.
Is there any way to do what I want to do? Giving the Azure user access to the master database (if even possible) seems like a bad solution.
Yes, I realize this may seem like overkill, but if I have the right credentials, I can add an IP rule for just about anywhere. Say I'm on a working lunch and need access. I add the rule and get to work. But say I forget about that rule, it could potentially just sit out there as an open invitation to someone who gets on that same network. I realize that this is slightly paranoid, but it just also seems logical to me that a firewall rule would be able to come with a built-in expiration. Am I missing something?

I think that the good way to do that would be to use Azure Automation for PowerShell commandlets - it can be scheduled, for example, once a day, and you can build a full Powershell management pipeline.
https://azure.microsoft.com/en-us/documentation/articles/sql-database-firewall-configure/
Take a look at the cloud-based graphical tool as well:
https://blogs.endjin.com/2016/03/using-azure-automation-to-run-vms-during-office-hours-only-using-graphical-runbooks/
Basically, you will need to change the main part to the SQL Azure commandlets.
If that is the helpful answer, please mark it as a helpful or as the answer. Thanks!

Related

Securing SQL Server database from Domain Admin

I have inherited a SQL Server box with a series of databases and it has Windows Auth for creation/maintaining the well-baked and established databases. The box itself has many other services which require a user to login as admin to maintain.
I now have to create a new database on the server that only a select few in the company, including IT, will have access to. So I'm kind of chasing my tail on the best place to start.
I want to continue to give the guys the admin level access they require to all the other stuff on this box but limit them on SQL Server options so I can better manage the databases and secure them. What might be the best way to unwind the Windows Authentication method and dole out databases / create opportunities for those users while securing new databases they should not access? Am I even going in the right direction by deviating from the Windows Auth method?
One of the primary reasons for creating a second instance on a server is security. By creating a second instance you basically re-start security over again. So this is an option you might consider for your new database. IE Creating a second instance and putting the "secure" database on it.
A few things you should also consider.
First, yes you should unwind your security as possible and give out the minimum security required for any given user/group. This is a best practices thing. Never give out dbo or sysadmin permissions without an explicit reason to do so, and even then question it thoroughly to make sure that there isn't some other way around the problem. Never give out more permissions than are absolutely required.
Second, It is almost impossible to keep the administrator of the server the instance is on out of the instance if they really really want to get in. And I only say "almost" impossible because there may be a way that I don't know about. At the level of administrator for the server, or domain administrator for that matter you have to assume they can be trusted not to try to break in. You probably won't be able to keep them out anyway.
Last but not least if you can move your instance off of a server that has many other services which require a user to login as admin to maintain. This is a security nightmare first of all (as I said above) and second your SQL server will work better on it's own server. I've even heard advice from experts that say you should never remote into the server a SQL Server instance is on. And if you have to remote in definitely don't copy files around while remoted. Generally said the less going on on the server the happier SQL is.
You can remove the domain administrators ability to access the SQL Server by removing the BUILTIN\Administrators group from the SQL Server logins.
I wouldn't recommend moving away from Windows Authentication, as you would create a whole new set of security concerns you then would have to deal with.
Domain admins can
add themselves to any group (local or domain) that has has access to SQL Server
change the service account policies and log in with that
change SQL server to use a service account in case it uses a built in account
use any user account that has SQL Server access
change password to allow this
Do anything in the domain. At. All.
SQL Server always has Window Auth switched on so it is always available to Domain Admins
If it's that sensitive then it needs to be in separate domain or standalone or something.

Multiple database users for ASP.Net MVC project SQL Server Auditing, or roll our own?

We currently have a SQL Server 2008 instance set up for our ASP.Net MVC application, and the SQL Server instance uses built-in auditing (I believe CDC?)
We also have our ASP.Net application set up to use one connection string specified in web.config for the entire application, no matter who is logged in (of about ~50 users)
The problem: We want to be able to include among the audit information the username of the user who made the particular change in question.
It looks like we can only do that in one of two ways:
Change our application setup so that every single user gets their own database login. This would require us to use dynamic connection strings (perhaps not too terrible), but moreover it would be a pain in the ass to add a new user to the system and the admins could no longer do it automagically via the application's interface (I think).
Use another solution from within the ASP.Net app itself. This would allow us to trivially add any bit of information in the application we wish, but would involve scrapping the entire builtin solution and essentially starting from scratch with a significant effort.
Someone must have run into this problem before with auditing - is #1 feasible? Or is #2 the only way we can go here?
Thanks
Option #1 is pain for the admins, a little complicated code for "dynamic" connection strings, and calling sp_addlogin to create users. But the worst is that separate DB login for every user also allows them to query DB directly (if they know instance & database names, which could leak to them in any way and "see" DB server through the network). Direct access to the DB is something that may crash every application. Don't do it, unless you're very sure that DB server is not directly reachable to the users.
About #2. How about adding column "LastModifiedLogin" to every table, where you put login of logged in user during every insert/update? This shouldn't crash CDC and you got what you want. However auditing delete is little problematic, because you issue statement and have no longer row where you could place the login. You may organize seperate "DeleteAudit" table where you put name of table, row identifier and user login on every delete, but that's only rough idea.
If you use NHibernate for data access, I would advise you to consider switching CDC to NHibernate Envers, which is very neat solution.

Application vs SQL server 2008 accounts issue

Good day all,
I am studing the following case:
Scenario: An application connects to the production database(SQL server 2008) using a generic "SA" user instead of the domain user. This is making traces\logs\organization harder, because everything is flagged as done by SA user!
NOTE: In the application the domain user/password is used, the generic account is only regarding to the database.
Questions: What would be the best pratice in this case? every user should have an account to log in the database? (sql using windows authentication) there are +- 500 users is that an issue regarding to database performance? or a generic account is indicated?
Many thanks!
As others have mentioned, Active Directory and Windows Authentication might be more appropriate if that's an option. But if not...
If the application has a central place that creates the connection & transaction prior to update, you may be able to use SET CONTEXT_INFO to pass along the "real" application user while still using a shared SQL account for the login.
Then in your auditing triggers you can pull the information back out again using the CONTEXT_INFO() function
This is the approach used by at least one commercial auditing tool
See also similar SO questions here and here which reference context_info and a blog post Exploiting Context_Info for Fun and Audit which gives an NHibernate example.
Nitpick on something else in your question: you said it's using sa user. Maybe that was just an example, but probably the application should not have so many rights on the server. Create a user with only the rights needed for the particular database(s) that application uses. This limits the impact of any future security vulnerability (e.g. SQL Injection) in your application. And to take it one step further, you might have one connection string with a read-only user account, and then at the point where you create a transaction to update data, switch to a connection string with the read/write user account. You still get most of the benefits of connection pooling, but you limit even further the impact of any application-tier bugs.

Constrain LINQ2SQL Datacontext to specific SQL Application Role

In SQL Server you are able to have application role security, through which you are able to for example give specific permissions that originate from specific applications.
You can execute sp_SetAppRole() to set the application role but was wondering how this could be accomplished when using a LINQ2SQL datacontext with the least amount of friction.
I've seen this link:
http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/e25e98a6-b0ac-42fc-b70c-2b269a7fa1cb but was hoping for a cleaner approach/
My conclussions (see below section for the why):
Using SQL application roles doesn't plays well with connection pooling and also shouldn't be used directly in final user apps (only on a business tier).
The SQL alternative would take away a lot of advantages from using linq, as it relies in SPs.
My recommendation:
If you have a business tier/server, do authorization at the application level instead of relying on sql authorization. If you still want to authorize, have an account associated to the business tier application, and associate a normal role to it.
If it is a client app that connects directly to sql. The user will still have the permission to call whatever his(her) identity has access to, and the app password is there. If you are not comfortable with the user having that level of access, you need a business tier.
If you still want to proceed with the approach, turn off connection pooling. To reduce the open/close overhead, open connections explicitly.
Full explanation/references:
One issue is it doesn't plays well with connection pooling. That is regardless of linq2sql. See at the end of this in msdn.
There are 2 alternatives since sql server 2005 (msdn link), one is also mentioned in the thread you linked to, but it also points out it can go wrong.
Note that its an unsecured option in a 2 tier scenario, like when the application used by the clients connects directly to sql. In those cases the pwd for any application in the client's computer would be exposed in those. Its more secure if it is a business tier the ones that connects, but that's precisely the case where you really want connection pooling.
The another alternative mentioned in my second link to msdn, works well with connection pooling. It is based on stored procedures, and the execute as statement. The execute as is called inside the procedure, and after the procedure is executed the context is reverted. That is great but really would be giving away a lot from what you get with linq2sql by going the sp route.

SQL Server Authentication or Integrated Security?

We have some corporate intranet users using a WinForms app to work on a system with SQL server behind. Integrated Security is setup, allowing all users update and delete permissions, where application security limits how and where table updates take place.
However, some users are power users with SQL query tools at their disposal, and access the DB directly for building reports. However, with integrated security, they have default update rights on tables where they should not have, as the application apply rules to the updates.
Is this an example of where it's more appropriate providing the app with a central SQL authenticated login, whilst users get read only rights for integrated security?
As Jon mentioned stored procedures would give you the protection over direct table modifications. There are other options too. You can use SQL Server's "Application Role" (via sp_setapprole proc). This enables you to continue to use a separate ID for everyone but only at application connection time (through the front-end) are the user's rights elevated.
A major downside to using a shared ID is you lose track of who is submitting SQL to the server though if they're all internal you can get to the machine name.
Something else is concerning though. It sounds as if your users can connect to the database and run queries at will. You run a major risk of downtime in the application due to user behavior in the directly connected SQL sessions. If you can pull it off you may want to try to have a reporting database created that is updated at intervals that your business can tolerate, i.e., daily. HTH
I presume from the way that you've worded your question that your app executes sql statements directly. If you could refactor it so that it executes stored procedures, you could grant exec rights on the procedures and deny direct updating of the tables. This might not be possible though, depending on what your app does.
sql authentication is one option. Stored procedures are another. However, building more granular roles for assigning just the appropriate permissions to just the appropriate user types is where you should really be looking.
Additionally, I would really avoid giving these users direct access to the DB at all. Security reasons aside, it doesn't take much for a user who isn't proficient in SQL to accidentally execute a query that will swamp your database server and create an effective denial of service. Even pros can do this accidentally from time to time.
Instead, give them access to a reporting services or analysis services type solution, or use replication to give them access to a clone of the data. This way your production system is protected.
Personally I would do all application data access through stored procedures. I would set Integrated security to only allow users to run the SP's and not manipulate the data directly.
Advanced access can be given to DB admins to manipulate the data directly when needed.
Group based permissions will provide you with much more flexibility for access rights, and less administrative burden when controlling these with integrated security.

Resources