I have a winforms C# application which will have to send and receive information securely from a remote SQL Server. At the moment I've just tested it with the database on my machine using the inbuilt classes e.g. SqlConnection.
I need to connecting my program to a remote SQL Server, execute queries against it. Both computers are under my organisation's control, although the remote workers are off-site and may be using a 3G connection.
One option is to connect the two computers using a VPN, and then presumably the other computer is visible as if it was on the same network, then I can use my connection string as I have been doing so far, perhaps putting in the IP address. However the IT support people are grumbling about setting up VPNs.
I have heard of TLS/SSL but never used this before. Can i use it to send sql queries to a SQL Server directly?
The SSL connectivity for SQL Server is encrypting the server socket connection. With SQL Server, a temp certificate is created each time you start the SQL Server. On the client side, you let the client accept any certificate, and this ensures your socket is encrypted (still open to Man in the Middle attack). You can also use your own signed certificate on both sides for the SSL connection. The DBA's set this up, and there's nothing special to do on your end, other than possibly setting up your own certificate and changing the connection string.
MSDN Using SSL Encryption
Typically, the datacenters (or host-host) are connected via private lan / VPN tunneling, which is also encrypted, and in this case, it would be a second layer of protection. If you have a VPN, you could probably get away with the Servers built in SSL certificate. That saves you the work of having to maintain the certificates each year.
Related
I'm writing a VB6 application which connects with SQL Server. To secure the connection with the database I'm using MSOLEDBSQL as provider which supports TLS 1.2. I also enabled TLS 1.2 in my machine. I verified the connection status using sys. dm_exec_connections and SQL server displays all the connections are encrypted. To double confirm I tried to use the echomirage to check the traffic and the results are surprising. The data is not encrypted and I can read all the data flow as shown in the below image. My question is
This communication is really encrypted. If not why I'm seeing different status in SQL server
I read somewhere that TCP is binary protocol. If so, why I'm seeing plain text even if this communication is not encrypted?
This isn't a TDS issue (the protocol used by SQL Server). The same thing happens with your browser when you use a debugging proxy like Fiddler and trust the proxy's certificate, or configure it to use a trusted certificate. Most likely, you trusted EchoMirage's certificate during setup or through its Settings and forgot about it.
SSL/TLS protect agains Man-In-The-Middle attacks by verifying the other party through certificates. Encryption isn't enough. Without verification a proxy between client and server could pose as the other party, set up encrypted communications with each side, decrypt the packets it receives, inspect them and then encrypt them again using the other side's keys and send them along. Without verification neither client nor server would know someone intercepted the connections.
With SSL/TLS, a connection is established only if both parties trust each other's certificates. Both sides verify the certificates by checking either whether the certificate is explicitly trusted, or if it was issued by a Certificate Authority trusted by the application. If validation fails, the connection fails as well.
Fiddler, WireShark and other similar tools decrypt traffic by acting like a proxy and establishing communications on either side using their certificate. With certificate validation enabled though, the browser (or the SQL Server client) would reject the connection. If you try to connect to a web site through HTTPS while Fiddler is in use you'd get a red warning page saying that the connection isn't safe.
To allow such connections someone would have to go and explicitly trust the tool's certificate. All tools can do this through their settings, but all OSs require privilege elevation and user confirmation before they add the certificate to their trusted list.
By default, drivers and network libraries perform validation. To allow WireShark to intercept the SQL Server connection you'd have to either explicitly disable validation with TrustServerCertificate=true;, or trust the tool's certificate, which is probably something you already did and forgotten about it.
The page Using Encryption Without Validation in SQL Server Native Client in the docs explains what happens when you don't use validation, and warns against it.
If you use Encrypt=true and leave TrustServerCertificate to its default, false, WireShark or EchoMirage won't be able to intercept, much less decrypt the traffic. In this case :
Encryption occurs only if there is a verifiable server certificate, otherwise the connection attempt fails.
This is a TDS issue (the protocol used by SQL Server), and is not caused by WireShark in any way.
TLS encryption is only used during the login process to ensure that the credentials are not passed unencrypted over the network.
After that, the remaining bulk-transfer of queries and result sets are not encrypted on the wire.
In order to enable encryption for data (and not just for the login process), you need to use the Use Encryption for Data connection string keyword in your connection string:
Use Encryption for Data=true
Use Encryption for Data
SSPROP_INIT_ENCRYPT
"Specifies whether data should be encrypted before sending it over the network. Possible values are "true" and "false". The default value is "false"."
Be aware: If you enable encryption for data, and the server doesn't have a valid certificate (i.e. the default), then you will get an error when connecting. The client will detect the server presented an invalid certificate, and stop the connection. In order to make your system reliable, you need to include Trust Server Certificate=true in your connection string:
Use Encryption for Data=true;Trust Server Certificate=true
A better alternative is to turn on the option on the server that forces encryption for data, and do not specify Use Encryption for Data or Trust Server Certificate in your connection string.
When it is the server that requires the encryption, the client will not care about the certificate presented by the server (excluding MSOLEDBSQL19, which is broken by default, and you will need to specify Trust Server Certificate=true even when it was the server who wanted the encryption in the first place.
I have added a database via phpmyadmin on a server. I can access it via http://ipaddress/phpmyadmin . but when i try using those credentials to connect to that db on a c# app , i get the error : unable to retrieve the list of database.
I don't have the right to access the server. I have a user who has rights to two db which i can see when i remotely connect to that server's phpmyadmin. Is it possible that i have right to the db just via phpmyadmin but can't access it via app because i don't have the right to do it because mysql is forbidding it ? I also have a raspberry pi handy. is using it as a db server a better alternative than this ?
Since phpMyAdmin runs on a web server, most people install it on the same machine the database is running on and access it remotely through the network. That means their phpMyAdmin is communicating with MySQL locally, often without the connection leaving the server. Your C# application, on the other hand, is a compiled application that would likely run on your client machine, not the server - meaning any connection from the application to the database is occurring through the network (or internet, depending again on your configuration). Since exposing the MySQL port is generally a bad idea, your MySQL may be configured to only listen locally, or you may have a firewall or NAT connection blocking you from even reaching the server. If that's the case, you may need to rethink how you'll communicate with the database (oftentimes exposing an API is a better solution than opening port 3306 to the world).
It's also possible you're using two different user accounts. To MySQL, an individual user account consists not only of the username, but also the hostname. You can use a wildcard hostname (%) which means all hosts, except it's really "all hosts connecting via TCP/IP networking connection."
It's possible that your application and your phpMyAdmin are using two different connection methods; one using TCP/IP and the other using sockets. Check which phpMyAdmin is using (the easiest way to do so is to look at the host phpMyAdmin is connecting to; 'localhost' is a socket connection and '127.0.0.1' is networking). Configure your C# application the same way.
I am making an application in C# that is supposed to work As CLIENT/SERVER architecture the application accesses to the server only to connect to the database. When I started developing the application I found that I had to make a connection string to access the database and then I made the following $"Server = {server}; Database = {dataBase}; Trusted_Connection = True;" which is working now and went to do a test on a machine where the local windows user does not have access to the SQL Server and hence I noticed that only
user at the time of creating the SQL instance in the Mixed Mode option
is one that have access to the SQL server if you are logged in to windows and are using the application. With little experience in developing such applications, I decided to come here to find help in how we can overcome this kind of challenges in desktop applications for .NET. Thanks in advance!
Windows SQL server uses the currently logged in windows user [At the server] to authenticate a connection request. For remote computers, this may not be effective. Rather, it's better to use the username and password authentication method for remote hosts. Kindly make sure that your server is set to mixed mode authentication and follow the following steps.
Create a new user who uses username and password to login. Visit [https://www.supremainc.com/en/node/618] as suggested by Aqib
From the windows firewall, allow incoming connections to access SQL server from outside computers by setting inbound rules in your firewall to allow connections through SQL server port. You may need to check the port your SQL server is listening to though the default port is 1433.
Visit [https://docs.syskit.com/spdockit/v7/faq/troubleshooting-sql-server-connection/inbound-traffic/] for instructions on how to setup the firewall
Make sure that the remote computer is connected to the server. You can do a simple ping to the server. You can use ip-address or server-name / url for checking the connection. [https://iihelp.iinet.net.au/How_to_run_a_ping_test]
Make sure your SQL server is started and run your application on the remote computer.
Thank you
If you want to use a SQL user, you first need to create a SQL user with the appropriate permissions (usually datareader and datawriter) on the database
How to create a SQL user on a database
Then instead of using Trusted Connection, you need to explicitely define the username and password in the connection string like this:
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
You can use SQL connection strings website as a reference for the various options
We are using v6.9.9 of the .Net MySql Connector to access MySql using this connection string, specifying that SSL is required.
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
SSL Mode=Required
Our DBA has turned on support for SSL, but during my testing, I am able to connect to the server regardless of whether I have certificates installed on my machine, and also regardless of whether I have "SSL Mode=Required" or not.
However, when my DBA disabled SSL, if I use the above connection string, I got an error that SSL was not enabled.
Therefore, I really just don't know if my network traffic is being encrypted or not. How can I verify?
--
My question is a bit of a duplicate to this one with no accepted answer.
How to check whether a MySQL connection is SSL encrypted?
Some recommend using WireShark to test. Does anyone have step-by-step instructions on how to use this tool to verify my SSL connections?
--
This link talks about calling "status" from the MySql client.
https://dba.stackexchange.com/questions/36776/how-can-i-verify-im-using-ssl-to-connect-to-mysql
I asked my DBA to try it - but he isn't able to call that method against my connection, only against his local connection. Is there anyway to call this, for example, within my c# code?
I tried this, but I don't think the returned values tell me if the connection is SSL or not.
SHOW SESSION STATUS LIKE '%Ssl%';
Anyone with detailed information on how to verify my SSL connections would be greatly appreciated! Thank you!
Didn't work a lot with databases, but network/wireshark expertise is enough for you task. So what should you do:
Prepare capture setup using this tutorial
Start sniffing network with wireshark and perform some queries to your database
Filter traffic by database IP-address and/or port using display filter, so irrelevant packets aren't shown
Examine displayed packets. Compare them to sample of MySQL over TCP and to sample of MySQL over SSL. Hint: you can see queries as a plain text in unprotected connection, while SSL makes packet payload look like bunch of random garbage.
I have created a windows service and want to connect to SQL server 2008 over internet. The issue is that although I can connect it locally and with the local IP, my server is behind a firewall. Since there is a Sharepoint server on the web on the same server, I know that the system is on the internet.
What should be the connection string to connect to the server from outside the local network and from anywhere in the world?
If it's behind a firewall, you'll have to open port 1433 to incoming traffic. Other than that, the connection string should be the same as the internal one, only using the external IP (if you don't know it: http://www.whatsmyip.org/). You'll need to make sure that mixed authentication is enabled, because of course you can't connect using Windows domain credentials over the internet.
I should probably mention it's not a very good practice to expose your SQL Server to the outside world ... but you know that, right?