Docker Community Forums

Share and learn in the Docker community.

Connect to the internet from a Windows container behind a http proxy


(Dogtail9) #1

I am using Docker for Windows
Version 17.09.0-ce-win33 (13620)
Channel: stable
8c56a3b

on Windows 10
OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.15063 N/A Build 15063

I am trying to run a Windows container behind a http proxy server. I have added my proxy information in the Docker settings dialog. I can pull images from Docker Hub so the proxy settings seems to work as expected.
When I run a Linux container it can access the internet just fine but when I run a Windows container it does not use the proxy and I can not access the internet. I useed the Invoke-Webrequest cmdlet to test the connectivity to the internet from my container. I tried to add the proxy settings to my Windows container as well.

First I added the key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer in the registry.

I tried to add the value in two different ways
{myproxy}:{myport}
and
http={myproxy}:{myport};https={myproxy}:{myport}

I tried to set the proxy with netsh winhttp set proxy proxy-server=“http={myproxy}:{myport};https={myproxy}:{myport}” bypass-list="{mybypasslist}"

I tried both at the same time and separate. I tried to do everything in the Dockerfile and in the powershell prompt in the container. Nothing works. The Invoke-Webrequest cmdlet do not use the proxy server when making a call to the internet.
I can see in Wireshark that the container tries to call the IP for the url not the IP for the proxy server.

I also tried to set the environmentvariabels HTTP_PROXY and HTTPS_PROXY on both my docker host and in the Windows container. Did not work.

I think i tried every combination of the above.

Just to verify that nothing is wrong with our proxy server I tried to specify the proxy in the Invoke-Webrequest like this:
Invoke-WebRequest -Uri $url -Proxy $proxy -OutFile install.ps1 and it works! I can see in Wireshark that the proxy server is called with the http request.

So my question is. How do I specify the proxy server a Windows container should use?


(Sam) #2

your netsh command is incorrect

see


(Dogtail9) #3

Thank you sdetweil for replying.

Can you explain what I am doing wrong? I don’t see it.

https://technet.microsoft.com/sv-se/library/cc731131(v=ws.10).aspx?f=255&MSPPError=-2147217396


(Sam) #4

set HTTP_PROXY=http://proxy_userid:proxy_password**@**proxy_ip:proxy_port


(Dogtail9) #5

Now I also tried with username and password. Still does not work.

As I said before.

Without username and password in the proxy url. I just can not get the Windows container to pick up my proxy settings.

Anyone know of any documentation on proxy settings for Windows container. How am I suppose to do this?


(Ovidiu-Florin Bogdan) #6

I’ve been struggling with the same thing. I’ve even reported a bug on it, but it seems no one cares. https://github.com/docker/for-win/issues/1319


(Aemery) #7

Running into the same issue, I’ve tried all the steps mentioned in the original post, none worked for me either.


(Dogtail9) #8

I actually solved this problem.

I exported the registry from one of my servers that had the proxy settings to a reg-file.

Export the key [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings] to a file called proxy.reg. Then in your Dockerfile add the following lines.

COPY ./proxy.reg .
RUN regedit.exe -S proxy.reg

It turns out that Windows actually reads the values for the proxy from the [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections] key in the registry. This key is created when you click the OK/Apply button in the proxy config dialog in Internet Explorer (hard to do in a container)

function Add-ProxySettings {
    Param(
        [Parameter(Mandatory=$False)]
        [String]$Proxy
        ,
        [Parameter(Mandatory=$False)]
        [String]$BypassProxy
    )  
    
    Write-Host "Setting Proxy To: " $Proxy;
    Write-Host "Setting bypass list to: " $BypassProxy;
    
    [String] $start =  [System.Text.Encoding]::ASCII.GetString([byte[]](70, 0, 0, 0, 25, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0 ), 0, 16);
    [String] $endproxy = [System.Text.Encoding]::ASCII.GetString([byte[]]( 233, 0, 0, 0 ), 0, 4);
    [String] $end = [System.Text.Encoding]::ASCII.GetString([byte[]]( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 0, 36);
    
    [String] $text = "$($start)$($Proxy)$($endproxy)$($BypassProxy)$($end)";

    [byte[]] $data = [System.Text.Encoding]::ASCII.GetBytes($text);
    $regKeyConnections = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
    Set-ItemProperty -Path $regKeyConnections -Name "DefaultConnectionSettings" -Value $data
 
    Get-ItemProperty -Path $regKeyConnections
}

I made an attempt to create a powershell script that sets the encoded registry settings as well. Use it with cousion, I have not used this in production yet. And yes, this only works in the WindowsServerCore image. The NanoServer images does not have the Internet Explorer installed so the registry keys do not exists. If you want to use tha NanoServer image you have to find another solution.

My company also has its own CA so I had to add our root-certificate to the container to get SSL to work for internal https requests. You can do that with the following line in the Dockerfile.

RUN Import-Certificate -FilePath CorpRootCert.der -CertStoreLocation Cert:\LocalMachine\Root

I hope this helps because I spended several days to figure this one out.

/Christer


(Aemery) #9

Tried your fix and it worked. Thanks a lot for sharing!

Would love to have it supported by Docker without having to manually modify the registry though.