9

Working with debian linux inside a docker contaier. I have sqlcmd working properly and the neseccary drivers are installed and locatable. I know the server exists:

root@0feafecac36f:/home/shiny# nmap -p 31010 -sT xxx.xxx.xxx.xxx

Starting Nmap 7.60 ( https://nmap.org ) at 2018-01-25 20:46 UTC
Nmap scan report for nile-h.tmthk.org (xxx.xxx.xxx.xxx)
Host is up (0.019s latency).

PORT      STATE    SERVICE
31010/tcp filtered unknown

Nmap done: 1 IP address (1 host up) scanned in 0.59 seconds

But, for the life of me, I cannot figure out how to connect using sqlcmd, and I am not sure what tricks I have at my disposal to help. This command results in an error:

sqlcmd -S nile-h.tmthk.org,31010 -U "*********" -P "********"
Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login timeout expired.
    Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : TCP Provider: Error code 0x2749.
    Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not
    accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..

I have confirmed that the user name and password are correct. So, what could be going on here? Any ideas? I've tried many iterations of the sqlcmd to try to get it right but so far nothing is working.

EDIT: Telnet

root@0feafecac36f:/home/shiny# telnet xxx.xxx.xxx.xxx 31010
Trying xxx.xxx.xxx.xxx...
telnet: Unable to connect to remote host: Connection refused

EDIT: tcptraceroute

root@0feafecac36f:/home/shiny# tcptraceroute xxx.xxx.xxx.xxx 31010
Selected device eth0, address 172.17.0.2, port 33859 for outgoing packets
Tracing the path to xxx.xxx.xxx.xxx on TCP port 31010, 30 hops max
 1  172.17.0.1  0.241 ms  0.179 ms  0.156 ms
 2  nile-h.tmthk.org (xxx.xxx.xxx.xxx) [closed]  1012.571 ms  1003.511 ms  1003.485 ms

EDIT: ip route get

root@0feafecac36f:/home/shiny# ip route get xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx via 172.17.0.1 dev eth0 src 172.17.0.2
    cache

EDIT: Dockerfile

FROM r-base:3.4.0
RUN apt-get update && apt-get install -y \
apt-utils \
curl \ 
libcurl4-openssl-dev \
libssl-dev \
r-cran-rjava \
gnupg2 \
r-cran-rodbc \
unixodbc \
unixodbc-dev \
apt-transport-https \
debconf-utils \
gcc  \
libct4 \
libsybdb5 \
tdsodbc \
sqsh \
mlocate \ 
sudo \
gfortran
ENV PATH="/opt/mssql-tools/bin:${PATH}"
RUN useradd -u 5555 -m -d /home/shiny -c "shiny user" shiny
ADD . /home/shiny/
RUN chown -R shiny:shiny /home/shiny 
RUN chmod 755 /home/shiny/install_sql.sh
WORKDIR /home/shiny
RUN Rscript installRpackages.R
RUN chmod 755 /home/shiny/install_sql.sh && /home/shiny/install_sql.sh
RUN    R -e "install.packages('devtools')"
RUN    R -e "devtools::install_github('rstudio/DT')"
RUN    R -e "devtools::install_github('timelyportfolio/parcoords')"
RUN    R -e "devtools::install_github('ropensci/plotly') ;  library(plotly)"
RUN    R -e "devtools::install_github('rstudio/crosstalk',force=TRUE) ;  library(crosstalk)"
RUN    R -e "install.packages(c('plotly'), dependencies = TRUE, repos='https://cran.rstudio.com/')"
RUN wget "http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb"
RUN sudo apt install ./libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb
USER shiny 
EXPOSE 7777
CMD Rscript start.R 

And finally, the install_sql.sh called by the Dockerfile:

curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.10/prod.list > /etc/apt/sources.list.d/mssql-release.list
apt-get update
ACCEPT_EULA=Y apt-get install msodbcsql
# optional: for bcp and sqlcmd
ACCEPT_EULA=Y apt-get install mssql-tools
# optional: for unixODBC development headers
apt-get install unixodbc-dev
Stu
  • 1,543
  • 3
  • 17
  • 31
  • Add output of `telnet xxx.xxx.xxx.xxx 31010` to your question. – Cyrus Jan 25 '18 at 21:28
  • `Connection refused`. Your Container can't reach the server. – Cyrus Jan 25 '18 at 21:32
  • Clearly it cannot connect, but any idea why that might be? It can point to the IP address fine. What should I try next? – Stu Jan 25 '18 at 21:32
  • Check if the output of `ip route get xxx.xxx.xxx.xxx` is conclusive and try `tcptraceroute xxx.xxx.xxx.xxx 31010`. Is the SQL server accessible from outside the container? – Cyrus Jan 25 '18 at 21:39
  • I wil ltry this now. Yes, the SQL Server (actually it's a cluster of servers) is accessible from outside the container (windows). Thanks again for your help. – Stu Jan 25 '18 at 21:43
  • 1
    I recommend adding your Dockerfile or docker-compose.yml to your question. – Cyrus Jan 25 '18 at 21:53
  • Good suggestion. Adding now. – Stu Jan 25 '18 at 21:54
  • Is TCP enabled for SQL on that port? Is it being blocked by a firewall (from either end)? – SMM Jan 29 '18 at 20:27
  • you're missing a `docker inspect` for the container. Are you publishing the container port 1433 as host port 31010? Besides that, why are you exposing port 7777 and not 1433? – fernandezcuesta Jan 29 '18 at 21:40
  • @fernandezcuesta 7777 is where I host the image for browser connectivity for the R shiny application. 31010 is the port of the server cluster where i need to get authenticated and open connectivity with the database. I will check out `docker inspect`! Thank you. – Stu Jan 29 '18 at 22:12
  • @SMM yes TCP is enabled. I will discuss firewall with the database admin to see what they say. – Stu Jan 29 '18 at 22:12
  • It's a firewall issue outside docker container as signaled by nmap output saying the port is _filtered_. From nmap docs _Filtered means that a firewall, filter, or other network obstacle is blocking the port so that Nmap cannot tell whether it is open or closed._ – LMC Jan 30 '18 at 23:23
  • @LuisMuñoz Is there anyway for me to know if it's my window's machine firewall or the server firewall? – Stu Jan 31 '18 at 22:34
  • 1
    I'm not an expert on window$ but try to run [tcproute](https://support.logicboxes.com/helpdesk/index.php?/Knowledgebase/Article/View/11/37/using-tcp-traceroute-on-windows-and-linux) on your specified port. If you have ssh access to that server you can create a tunnel over ssh to skip firewalls. Anyway, according to your post, port is closed at `nile-h.tmthk.org (xxx.xxx.xxx.xxx) [closed]`. – LMC Jan 31 '18 at 22:39
  • The port is 1433 by default, why is your expectation it's 31010? 1433 does not appear in your config at all. (Unless I am blind, sorry.) https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-mssql-conf#tcpport – ta.speot.is Feb 01 '18 at 12:02
  • Check the SQL Server error log to verify listening interfaces and ports the database engine is using: `sudo cat /var/opt/mssql/log/errorlog | grep listening` – Dan Guzman Feb 01 '18 at 12:17
  • Not a Docker expert...have you opened the SQL management console to see what services are running? Are you sure it's setup to except remote connections there – Ctznkane525 Feb 04 '18 at 01:03
  • is your SQL server also a Docker container? If it is, are you running it within the same docker network and linking it correctly? – juanecabellob Feb 05 '18 at 12:53

2 Answers2

6

Judging by the nmap output you have shared I believe this to be a firewall issue or the server SQL Server itself blocks access. According to man nmap:

The state is either open, filtered, closed, or unfiltered [... ] Filtered. means that a firewall, filter, or other network obstacle is blocking the port so that Nmap cannot tell whether it is open or closed.

Reading the sqlcmd output (A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible) also points in this direction according to this Microsoft post which also offers some possible solutions.

IF the SQL Server is managed by yourself, you may check its logs to see why it refuses your connection and also add a firewall rule to allow access from your container. IF that's not the case, you may need to talk with the admin of that server and ask him to add your IP in the firewall list/accepted connections list in the server's configuration file.

If firewall is not your issue, please try applying the below settings to your SQL Server and re-test the connection.

Set "Listen to All" to No in the SQL Server Configuration Manager > SQL Server Network Configuration > Protocols for [instance name]. And under IP Address change 127.0.0.1 to the [ip] used to connect. Don't forget to restart the SQL Server!

Other tip: check your firewall (or temporaly disable it for testing). Also allow remote connections in SQL Server properties > Connections. See above posts.

Life safer was this command: nc -zv <ip> 1433
It should say Connection to 1433 port [tcp/ms-sql-s] succeeded!

The original source is here.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
AnythingIsFine
  • 1,777
  • 13
  • 11
1

Reading from your question, I'm assuming you want to connect to your local SQL Server from inside Docker.

SQL Server can be connected to over TCP/IP:

  1. Open SQL Server Configuration Manager and make sure TCP/IP is enabled;

  2. Make sure SQL Server is listening on all IP addresses.

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
  • How? I'm running Linux Ubuntu and I'm also running SQL Server inside a docker container. Where is that SQL Server Configuration Manager? How can I open it? – Saeed Neamati Jun 19 '21 at 18:44
  • 1
    @SaeedNeamati I was on Windows and the SQL Server Configuration Manager gives this GUI. In Linux the process you'd want to achieve is the same except that you don't have the GUI. [This article might help](https://www.mssqltips.com/sqlservertip/4735/sql-server-configuration-manager-for-linux/) – Tiago Martins Peres Jun 19 '21 at 20:10