I am completely new to Amazon Web Services and I am trying to implement a Virtual Private Cloud with public and private subnets. A private subnet will host my database servers and public subnet will contain my application's web servers. I followed Amazon's own step-by-step tutorial to achieve this:
Scenario 2: VPC with Public and Private Subnets
I have configured all the VPC security groups as described in the tutorial and I successfully managed to get my web servers talking to my database servers. I also want to remotely connect to the database from MSSQL Management Studio on my local machine so I can create/drop schemas and generally see what's inside the database. However, I cannot connect to the database servers at all.
Part of the problem is that I am not sure exactly what I am meant to be connecting to. Prior to doing this tutorial I created a simple database and used its endpoint as the URL and I could remotely connect to it from my local machine. Now, since the database servers are on a private subnet and can only communicate with the outside world via a NAT instance, does this mean that I should use NAT's elastic IP as a database URL and add extra rules to NAT's security groups? My knowledge of networking is somewhat lacking so I am not too sure and the tutorial doesn't help here either.
My security groups contain the following entries:
NAT instance security group inbound:
Port | Source
22 | my external ip
80 | 10.0.1.0/24 (private subnet)
443 | 10.0.1.0/24 (private subnet)
1433 | my external ip
NAT instance security group outbound:
Port | Destination
80 | 0.0.0.0/0
443 | 0.0.0.0/0
1433 | 0.0.0.0/0
Database security group inbound:
Port | Source
1433 | sg-d6ec33b9 (web servers security group)
Database security group outbound:
Port | Destination
80 | 0.0.0.0/0
443 | 0.0.0.0/0
Webservers security group inbound:
Port | Source
22 | 0.0.0.0/0
80 | 0.0.0.0/0
443 | 0.0.0.0/0
8080 | 0.0.0.0/0
Webservers security group outbound:
Port | Destination
80 | 0.0.0.0/0
443 | 0.0.0.0/0
1433 | sg-b5ec33da (database security group id)
Main routing table is associated with a private subnet (10.0.1.0/24) and has following routes:
Destination | Target
10.0.0.0/16 | local
0.0.0.0/0 | i-cf8605ad (NAT instance id)
Custom route table is associated with a public subnet (10.0.0.0/24) and has following routes:
Destination | Target
10.0.0.0/16 | local
0.0.0.0/0 | igw-a4ed3aca (internet gateway id)
So given this setup, what would I need to do to gain an external access to the database servers that are on private subnet an are protected by a NAT instance? Do I need to add/alter the rules in the security groups?
Thanks in advance.
Your problem is a little bigger than security group changes. The main problem is that your private vpc is private as in 'not internet accessible'.
You have several options to connect from outside:
Use a bastion machine as an intermediate hop (on the public net) and add relevant SG rules to hop form that machine into your precious DB. Your users will need to connect to that machine and then either run client tools on that machine to connect to the DB or setup a SSH tunnel to your DB (so your office machine could connect). This is not a great solution in term of users experience and in term of security (the bastion become a very big security risk) but it is simple to setup. (Note: since you are MS dude then please switch SSH for RDP [and cancel the tunneling thing])
Setup a VPN - bring a big gun to shoot a fly. Setup a VPN (either use AWS VPN termination, or setup an OpenVPN or similar stuff). Define the routing, SG rules, Keys clients and update here if you managed to configure this within a reasonable effort. I would not go for a full site-to-site VPN (to your office network) since you do not want every malware running in your office to reach your 'private' data center.
Create a little passthrough to your DB instance from your office. Ingredients:
A custom route from your office IP to the private network, Proper SG rule to allow office IP to DB SG, Elastic IP to make the instance internet reachable.
You could improve solutions 1,3 security by utilizing Dome9's Access Leases. This will allow you to restrict access to the bastion/passthrough and to enable them on demand for authorized users (disclaimer - I'm a proud Dome9'er)
Enjoy
Related
Following the Azure VM cluster tutorial provided by Microsoft (https://learn.microsoft.com/en-us/azure/developer/terraform/create-vm-cluster-with-infrastructure),
I have a resource group created in Azure.
Under the Resource group, I have created VN, subnets, etc.
Now, I have two VMs created in the resources group. Both of them have a LoadBalancer on top. I have added NAT rule to LB to connect to individual instance, while they both share the same frontend IP.
I have created a new resource Azure MSSQL server, in the Firewall rule of the SQL server, added the public ip of the LB to the Azure Server
I have now logged in to the individual VMs, and tried to access the SQL server from the VM, but I am unable to connect to it.
I tried normal ping <hostname>
it fails 133 packets transmitted, 0 received, 100% packet loss, time 295ms
Then I try telnet from IP address (ip address was received from ping )
and I get
Trying <ip_address>...
Connected to <ip_address>.
Escape character is '^]'.
When I try to connect using an application, I get this error
com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset ClientConnectionId:8b2f0e3b
-fda0-41af-b8dc-ce80d0760b82
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.jav
a:3806) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:2109) ~[mssql-jdbc-11.2
.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.prelogin(SQLServerConnection.java
:3517) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection
.java:3325) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:29
50) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnecti
on.java:2790) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:
1663) ~[mssql-jdbc-11.2.0.jre8.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1064) ~[
mssql-jdbc-11.2.0.jre8.jar:?]
at jet.server.db.core.ConnectorManager$ConnectionPool.£(ConnectorManager.java:712) ~[
JRESServlets.jar:?]
at jet.server.db.core.ConnectorManager$ConnectionPool.connect(ConnectorManager.java:4
32) ~[JRESServlets.jar:?]
at jet.server.db.core.ConnectorManager$ConnectionPool.getConnection(ConnectorManager.
java:504) ~[JRESServlets.jar:?]
at jet.server.db.core.ConnectorManager$ConnectionPool.getConnection(ConnectorManager.
java:487) ~[JRESServlets.jar:?]
at jet.server.db.core.DatabaseImpl.open(DatabaseImpl.java:839) ~[JRESServlets.jar:?]
at jet.server.db.core.GlobalDataService.<init>(GlobalDataService.java:103) ~[JRESServ
lets.jar:?]
at jet.server.db.core.GlobalDataService.init(GlobalDataService.java:37) ~[JRESServlet
s.jar:?]
at jet.server.ServerEnv.K(ServerEnv.java:2322) ~[JRESServlets.jar:?]
How do I make this work?
Azure SQL is only available through TCP port 1433. Check whether firewall is allowed outgoing TCP communication on port 1433.
You can check the connection by using below command:
Test-NetConnection -Port 1433 -ComputerName ServerName.database.windows.net
To resolve the error, make sure to open firewall in the path from Server like Windows Firewall, Corporate Firewall or Azure NSG (Network security group to allow access.
In the Azure SQL Server, select Networking and enable the below option:
Connect to the Azure Virtual Machine and restart SQL Server like below:
Reference:
IP firewall rules - Azure SQL Database | Microsoft Learn
In my Azure environment I have private SQL Server. To access SQL Server and databases I use a private endpoint. When I connect to SQL from VM in the same Virtual Network I have no problem. I have AKS in the same Virtual Network I try to connect to the database from pod but Kubernetes DNS didn't resolve SQL Server FQDN correctly. DNS name resolved to external IP but private SQL didn't have external access.
This is example how SQL Server resolved from VM:
nslookup *****************.database.windows.net
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
*****************.database.windows.net canonical name = *****************.privatelink.database.windows.net.
Name: *****************.privatelink.database.windows.net
Address: 172.0.8.4
This is correct address to Private Endpoint
And how it resolve from pod in AKS cluster:
kubectl exec -it dnsutils -- nslookup *****************.database.windows.net
Server: 10.0.0.10
Address: 10.0.0.10#53
Non-authoritative answer:
*****************.database.windows.net canonical name = *****************.privatelink.database.windows.net.
*****************.privatelink.database.windows.net canonical name = dataslice6.******.database.windows.net.
dataslice6.******.database.windows.net canonical name = dataslice6*******.trafficmanager.net.
dataslice6*******.trafficmanager.net canonical name = cr5.******-a.control.database.windows.net.
Name: cr5.*******-a.control.database.windows.net
Address: 40.78.225.32
How I can set connection pods from AKS to SQL Private Endpoint?
Create a firewall rule on the Azure DB Server with a range of IP addresses of the AKS Cluster nodes.
Create a VNet Rule on the Azure DB Server that allows access from the subnet to the AKS nodes. This is used in Microsoft.Sql VNet Service Endpoint enabled on the cluster subnet.
If Azure SQL Database is restricted to allow only private access, we can use cross-region private endpoints via Azure Private Link for the Azure SQL database or in region private endpoint with Azure Global VNet-peering.
To connect to AKS from SQL Private Endpoint, we will use VNet Peering with Azure SQL Database Private Link.
For more in detail, please refer below links:
https://learn.microsoft.com/en-us/azure/aks/command-invoke
https://arsenvlad.medium.com/aks-workload-accessing-azure-sql-database-in-another-region-cb6fb30545e4
https://argonsys.com/microsoft-cloud/library/private-aks-and-acr-using-private-endpoint-part-1-2/
https://blog.crossplane.io/azure-secure-connectivity-for-aks-azure-db/
I guess your SQL server's private IP is falling in the docker bridge's CIDR range which is found in the Networking menu in your AKS cluster. If it falls in the range, then docker won't allow the request to go out of docker network.
I have SQL server 208 R2 hosted on AWS. Can I access that SQL server through my web application on local machine without VPN?
What connection string we need to give in web.config. So I no need to have SQL server on my local machine.
I can run and test my application without having SQL server on my local machine.
If your SQL Server is publicly accessible, then you can simply connect directly to it. It's a bad practice to expose database servers directly to the internet, however, so don't do this.
If your SQL Server is not publicly accessible, then you can connect to it via an SSH tunnel. You would launch a publicly-accessible EC2 instance, restrict its security groups to allowing SSH from your local IP address, and then use SSH on your local machine to port-forward to the SQL Server via the SSH tunnel. You can then connect your database client to the local port on your machine and that will be forwarded to the SQL server via the SSH tunnel. Here's an example.
The SQL Server will also have to allow inbound connections from your EC2 instance.
Assuming it's the default SQL Server instance listening on port 443, and your EC2 instance has a public IP address, you could do the following:
Enable access to your EC2 instance through port 443 from your local machine public IP.
Configure Windows firewall to allow access through port 443
Ensure TCP/IP protocol is enabled for your SQL Server Instance
Use data source=<the public ip address of your E2 instance> in the connection string.
To enable access to your EC2 instance through port 443 from your local machine public IP do the following:
Go to AWS mangement console.
Go to EC2 Service.
Click on Running Instances
Click on your EC2 instance running SQL Server
Click on one of the security groups listed on the Description tab.
Click on the Inbound tab.
Click on the Edit button
Click on Add Rule button
Select Custom TCP rule on the Type dropdown list.
Enter 443 on Port Range.
Select My IP on Source dropdown list.
Enter "SQL Server from My local IP" on Description text box.
Your public IP address might change over time, so you might need to update the source when this happens.
To configure Windows firewall to allow access through port 443 open an RDP session to your EC2 instance and use Windows Firewall with Advanced Security tool and add the the rule.
To ensure TCP/IP protocol is enabled for your SQL Server Instance do the following:
Open an Remote Desktop session to your EC2 instance.
Open SQL Server Configuration Manager.
Expand SQL Server Network Configuration
Click on Protocols for
Enable TCP/IP protocol if not enabled.
Hope it helps
I am having a real hard time establishing SQL connection between servers within a Azure network. The really odd thing is that I can connect to SQL from my home machine which is outside the VM network. It seems like some type of network issue from within the VM domain which I have not been able to identify yet.
My configuration is as follows:
I have three VM's (Active Directory, Sql Server, and an App Server)
I am trying to establish SQL connection from app server to sql server
Both VM's Windows Server 2012
All servers are on the same azure network, affinity group, domain
All servers connected to the domain and have IP's
I can see DNS is resolving because I can ping the sql server from the app server using the sql server's computer name
I created Firewall rules allowing in/out on port 1433 on both servers
SQL Server is listening on the default port because of this command executed on the SQL Server (i'm not understanding the 0.0.0.0 IP though which may be a problem) (I can connect from home so I think this is ok)
netstat -an | find ":1433"
TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING
TCP [::]:1433 [::]:0 LISTENING
I created public & private endpoints on SQL for default sql port 1433
I can actually connect to SQL Server from my home machine
I have temporarily turned off firewalls on both servers
tracert from the app server looks like this.
tracert spsql01
Tracing route to spsql01 [10.0.0.7]
over a maximum of 30 hops:
1 * * * Request timed out.
2 * * * Request timed out.
3 * * * Request timed out.
4 5 ms <1 ms 1 ms spsql01 [10.0.0.7]
Trace complete.
On the App Server i create a connection.udl file to test the connection to my SQL Server but it never passes the connection test.
Have you created the appropriate Windows Azure SQL Database firewall rules for your VMs in Windows Azure? You can use either the special 0.0.0.0 for all of Windows Azure or, better, provide the public VIP of your IaaS cloud service (not the private DIP of the individual VMs). The latter limits firewall access to only your cloud service, since the outbound connection to WASD will use your public VIP. Note that if you delete (or stop/deallocate) all the VMs in your cloud service you will lose the VIP.
I am not able to connect to a remote SQL Server.
I have done the following:
Enable TCP/IP protocol
turned Off the firewall
Start SQL Server Browser service.
But I'm still not able to connect to the server
Server Name:--ip\SQLSERVER
User--UserName
Pwd--PWd
I would do the following checks.
Enable TCP/IP protocol
Turn off the firewall on the server (don't know whether you turned off your client firewall or server firewall here)
Remote server is up and running
Remote server SQL server services are started and running
a) SQL Server agent
b) SQL Server (SQLSERVER)
Client machine is able to ping remote server (This is not mandatory. If ping is not working still it is possible to access server. If ping is working then one less thing to worry)
Finally post your error message if you get any, that will help us understand more clearly what could be wrong.
If you haven't already, try the following:
In Management Studio, right-click your server, and click Properties
Go to the Connections page and make sure Allow remote connections to this server is checked
Click on the Security page and, under Server authentication make sure that SQL Server and Windows Authentication mode is selected.
Also, make sure that both the server and client are using the same IP version (IPv4 or IPv6)
Did you check if your user has the right to connect to the server?
Look at the output of:
select host, user from mysql.user;
it should look like this:
+--------------+------------------+
| host | user |
+--------------+------------------+
| % | MyUserName |
| 12.12.12.123 | MyUserName |
| localhost | debian-sys-maint |
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
+--------------+------------------+
Let's look at the first 2 rows, the "%" under host means that you can connect from any IP.
The second row specifies the host (Just pick one of those options).
Hopefully, that helped.