I have a Linux Strongswan IPSec site-to-site connection up and stable to an Azure Cloud Network, I'm trying to route an sql connection with a python script through the tunnel to an Azure database in the clients network but I keep getting timed out responses and I can't tell if the connection attempts are going through the tunnel. Part of my python script is trying to resolve the address to the IP but I assume the firewalls of the client are stopping that. The returned error response from the attempted connection is below, and if even the connection was attempting I imagine would be a different error code -
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+instance+';PORT=1433;DATABASE='+database+';Authentication=ActiveDirectoryServicePrincipal;ENCRYPT=yes;TrustedServerCertificate=no;UID='+username+';PWD='+password)
pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
The right side connection public IP is used in IPSec.conf but the database and DNS IP's are private and set via the rightdns below, the database itself is on a separate host within that dns range(if I have that terminology right). The DNS connection is @xx.xx.xx.16 but the database is at xx.xx.xx.20, which I assume I should be able to get to without adding routes as it should be handled automatically with my config below?
I'll add my config and what I know so far below, but I can't seem to connect to the database.
IPSec.conf
#Debugging statuses and allow duplicate connections
config setup
charondebug="ike 2,esp 2,knl 2, cfg 2,mgr 1,enc 1,net 2"
uniqueids=no
#Config for connection and load this on start-up
conn ikev2-vpn
mobike=no
auto=add
compress=no
type=tunnel
keyexchange=ikev2
ikelifetime=28800
fragmentation=yes
forceencaps=yes
dpdaction=clear
dpddelay=45s
rekey=no
#left side config
left=xx.xx.xx.xx
leftid=xx.xx.xx.xx
leftauth=secret
leftsubnet=0.0.0.0/0
#right side config
right=xx.xx.xx.xx
rightid=xx.xx.xx.xx
rightauth=secret
rightsubnet=0.0.0.0/0
rightdns=xx.xx.xx.xx
ike=aes256-sha384-modp2048s256!
esp=aes256-sha256!
Firewall rules
Status: active
To Action From
-- ------ ----
Apache ALLOW Anywhere
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
500,4500/udp ALLOW Anywhere
53/udp ALLOW Anywhere # Open port DNS udp port 53
1433/tcp ALLOW Anywhere # Open port DNS tcp port 1433
500/udp ALLOW Anywhere
4500/udp ALLOW Anywhere
Apache (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
500,4500/udp (v6) ALLOW Anywhere (v6)
53/udp (v6) ALLOW Anywhere (v6) # Open port DNS udp port 53
1433/tcp (v6) ALLOW Anywhere (v6) # Open port DNS tcp port 1433
500/udp (v6) ALLOW Anywhere (v6)
4500/udp (v6) ALLOW Anywhere (v6)
Post forwarding has been enabled and set to what I assume is the default gateway xx.xx.xx.xx
*nat
-A POSTROUTING -s xx.xx.xx.xx -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s xx.xx.xx.xx -o eth0 -j MASQUERADE
COMMIT
*mangle
-A FORWARD --match policy --pol ipsec --dir in -s xx.xx.xx.xx -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s xx.xx.xx.xx -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d xx.xx.xx.xx -j ACCEPT
My pyodbc script is -
server = "Private IP within the clients network"
instance = 'clientsaddr.database.windows.net'
database = 'dbname'
username = 'user'
password = 'pass'
# test data
try:
result = r"Instance {0}\{1} is listening on port {2}.".format(
server,
instance,
sqlserverport.lookup(server, instance),
)
except sqlserverport.BrowserError as err:
result = err.message
except sqlserverport.NoTcpError as err:
result = err.message
print(result)
def conn():
#############################################
# PRE-REQUISITES
#############################################
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';PORT=1433;DATABASE='+database+';Authentication=ActiveDirectoryServicePrincipal;ENCRYPT=yes;TrustedServerCertificate=no;UID='+username+';PWD='+password)
cursor = conn.cursor()
if not debug:
# set log file
old_stdout = sys.stdout # store old stdout to revert back after script is finished
log_file = f'logs/netzero_log_{today.strftime("%d-%m-%y")}.log'
open_log_file = open(log_file, 'w') # open file for log storage
sys.stdout = open_log_file # set file to log rather than console
if not debug:
sys.stdout = old_stdout # back to built in console
open_log_file.close() # close log file
try:
main_func(True)
print("Successful")
except:
print("Failed")
def db_exe(query,c):
try:
if c.connection:
print("connection exists")
c.execute(query)
return c.fetchall()
else:
print("trying to reconnect")
c=conn()
except Exception as e:
return str(e)
dbc=conn()
print(db_exe("select * from users",dbc))
When the connection is up and stable ipsec statusall returns
IPSec StatusAll snippet