Skip to content

Conversation

@jimmystridh
Copy link

@jimmystridh jimmystridh commented Jan 29, 2026

Problem

When connecting to Azure SQL through an SSH tunnel or proxy (e.g., 127.0.0.1:11433), connections fail because SQL Server validates the hostname in the TDS LOGIN7 packet. The server receives 127.0.0.1 as the server name and rejects it with "Cannot open server '127.0.0.1' requested by the login".

Current workaround requires adding /etc/hosts entries mapping the real server name to 127.0.0.1.

Fixes #576

Solution

Add a --server-name flag that specifies the server name to send in the login packet, separate from the dial address (-S).

# Connect via tunnel on localhost:11433, authenticate as the real server
sqlcmd -S 127.0.0.1,11433 --server-name myserver.database.windows.net \
    -U myuser -P mypass -N -C

Implementation

  • Add ServerNameOverride field to ConnectSettings
  • Build the connection string using the override host/instance (so LOGIN7 uses the override)
  • Use a proxy dialer that rewrites the network dial target back to the original -S host/port
  • Skip override for named pipes

Allows specifying the server name sent in the TDS LOGIN7 packet
separately from the dial address. Fixes connections through SSH
tunnels or proxies to Azure SQL where the server validates hostname.

Refs: microsoft#576
@jimmystridh
Copy link
Author

@microsoft-github-policy-service agree

@dlevy-msft-sql dlevy-msft-sql added enhancement New feature or request Size: S Small issue (less than one week effort) labels Jan 30, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for overriding the server name used during TDS login (and related connection metadata) so sqlcmd can connect through tunnels/proxies (e.g., 127.0.0.1:11433) while authenticating as the real Azure SQL hostname.

Changes:

  • Introduces ConnectSettings.ServerNameOverride and applies it when building the connection string.
  • Adds a proxyDialer to rewrite the actual dial target while keeping the overridden server name for login.
  • Adds unit tests covering the new connection string behavior and dialer behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/sqlcmd/connect.go Adds ServerNameOverride and applies it during connection string construction.
pkg/sqlcmd/sqlcmd.go Attempts to attach a custom dialer when ServerNameOverride is set.
pkg/sqlcmd/dialer.go Implements a dialer that rewrites dial host/port while reporting an overridden hostname.
pkg/sqlcmd/dialer_test.go Adds unit tests for proxyDialer.
pkg/sqlcmd/sqlcmd_test.go Extends connection string tests to cover ServerNameOverride.

Comment on lines +65 to +68
// ServerNameOverride specifies the server name to use in the login packet.
// When set, the actual dial address comes from ServerName, but this value
// is sent in the TDS login packet for server validation.
ServerNameOverride string
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description/title mention adding a --server-name flag, but the repo currently has no CLI flag wiring for this new ConnectSettings.ServerNameOverride field (searching cmd/ shows no references). As-is, the new behavior is not reachable from the shipped sqlcmd commands; please add the flag (and help text) in the Cobra command(s) and map it into ConnectSettings.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment on lines +65 to +68
// ServerNameOverride specifies the server name to use in the login packet.
// When set, the actual dial address comes from ServerName, but this value
// is sent in the TDS login packet for server validation.
ServerNameOverride string
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description/title says this adds a --server-name flag, but the changes here only introduce ConnectSettings.ServerNameOverride and related plumbing. I couldn’t find any CLI flag wiring (searching the repo for --server-name/server-name returned no results), so this feature isn’t currently reachable from either the modern or legacy sqlcmd entry points. Please add the flag parsing and map it into ConnectSettings.ServerNameOverride (and update help/docs accordingly).

Copilot uses AI. Check for mistakes.
Comment on lines +299 to +303
mssqlConnector.Dialer = &proxyDialer{
serverName: connect.ServerNameOverride,
targetHost: serverName,
targetPort: targetPort,
}
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConnectionString() parses/normalizes ServerNameOverride via splitServer() (dropping protocol prefixes/port and separating instance), but ConnectDb() passes the raw ServerNameOverride into proxyDialer.serverName. If a caller provides an override like tcp:realsql or includes an instance/port, the host name sent via HostName() may diverge from the host/instance actually used in the connection string. Consider parsing ServerNameOverride in ConnectDb() the same way and using the normalized host (and instance if appropriate) consistently.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Size: S Small issue (less than one week effort)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide a way to specify target server hostname or specify username when authenticating with Azure AD CLI

2 participants