Asked  7 Months ago    Answers:  5   Viewed   30 times

At work we have to use a proxy to basically access port 80 for example, we have our own custom logins for each user.

My temporary workaround is using curl to basically login as myself through a proxy and access the external data I need.

Is there some sort of advanced php setting I can set so that internally whenever it tries to invoke something like file_get_contents() it always goes through a proxy? I'm on Windows ATM so it'd be a pain to recompile if that's the only way.

The reason my workaround is temporary is because I need a solution that's generic and works for multiple users instead of using one user's credentials ( Ive considered requesting a separate user account solely to do this but passwords change often and this technique needs to be deployed throughout a dozen or more sites ). I don't want to hard-code credentials basically to use the curl workaround.

 Answers

18

To use file_get_contents() over/through a proxy that doesn't require authentication, something like this should do :

(I'm not able to test this one : my proxy requires an authentication)

$aContext = array(
    'http' => array(
        'proxy'           => 'tcp://192.168.0.2:3128',
        'request_fulluri' => true,
    ),
);
$cxContext = stream_context_create($aContext);

$sFile = file_get_contents("http://www.google.com", False, $cxContext);

echo $sFile;

Of course, replacing the IP and port of my proxy by those which are OK for yours ;-)

If you're getting that kind of error :

Warning: file_get_contents(http://www.google.com) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 407 Proxy Authentication Required

It means your proxy requires an authentication.

If the proxy requires an authentication, you'll have to add a couple of lines, like this :

$auth = base64_encode('LOGIN:PASSWORD');

$aContext = array(
    'http' => array(
        'proxy'           => 'tcp://192.168.0.2:3128',
        'request_fulluri' => true,
        'header'          => "Proxy-Authorization: Basic $auth",
    ),
);
$cxContext = stream_context_create($aContext);

$sFile = file_get_contents("http://www.google.com", False, $cxContext);

echo $sFile;

Same thing about IP and port, and, this time, also LOGIN and PASSWORD ;-) Check out all valid http options.

Now, you are passing an Proxy-Authorization header to the proxy, containing your login and password.

And... The page should be displayed ;-)

Wednesday, March 31, 2021
 
ioleo
answered 7 Months ago
89

Sounds like your browser has the proxy configured wrong.

Aka "No proxy for" should contain localhost AND 127.0.0.1

Wednesday, March 31, 2021
 
NaeiKinDus
answered 7 Months ago
96

Am I suppose to create this in a seperate php file and then send a request to this code?

Yes. The code above should resend your request made from JS to a remote service on another domain. Which is what does the trick - enables crossdomain POST requests from JS.

<?php

$server_url = "http://example.com/";

$options = array
(
    CURLOPT_HEADER         => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT        => 60,
    CURLOPT_CONNECTTIMEOUT => 0,
    CURLOPT_HTTPGET        => 1
);

$service = $_GET["service"];

$request_headers = Array();
foreach($_SERVER as $i=>$val) {
        if (strpos($i, 'HTTP_') === 0) {
                $name = str_replace(array('HTTP_', '_'), array('', '-'), $i);
                if ($name != 'HOST')
                {
                    $request_headers[] = "{$name}: {$val}";
                }
        }
}

$options[CURLOPT_HTTPHEADER] = $request_headers;

switch (strtolower($_SERVER["REQUEST_METHOD"]))
{

    case "post":
        $options[CURLOPT_POST] = true;
        $url = "{$server_url}/services/".$service;

        $options[CURLOPT_POSTFIELDS] = file_get_contents("php://input");

        break;
    case "get":

        unset($_GET["service"]);

        $querystring = "";
        $first = true;
        foreach ($_GET as $key => $val)
        {
            if (!$first) $querystring .= "&";
            $querystring .= $key."=".$val;
            $first = false;
        }

        $url = "{$server_url}/services/".$service."?".$querystring;

        break;
    default:
        throw new Exception("Unsupported request method.");
        break;

}

$options[CURLOPT_URL] = $url;

$curl_handle = curl_init();

curl_setopt_array($curl_handle,$options);
$server_output = curl_exec($curl_handle);
curl_close($curl_handle);

$response = explode("rnrn",$server_output);
$headers = explode("rn",$response[0]);

foreach ($headers as $header)
{
    if ( !preg_match(';^transfer-encoding:;ui', Trim($header))  )
    {
        header($header);
    }
}

echo $response[1]; 

This is a slightly modified version of the script I use, unfortunately not well documented.

Hope it helps.

Wednesday, March 31, 2021
 
axiomer
answered 7 Months ago
47

To setup CNTLM for windows, follow this article. For Ubuntu, read my blog post.

Edit:

Basically, to use CNTLM in any platform, you need to setup your username and hashed password, before using http://127.0.0.1:3128 as a proxy to your parent proxy.

  1. Edit the config and add important information like domain, username, password and parent proxy.

  2. Generate hashed password.

    Windows cntlm –c cntlm.ini –H

    Ubuntu/Linux cntlm -v -H -c /etc/cntlm.conf

  3. Remove plain text password from the config and replace them with the generated passwords.

To check if working:

Windows cntlm –M http://www.google.com

Ubuntu/Linux sudo cntlm -M http://www.google.com/

For more detailed instructions, see links above.

Update:

Just for completeness sake, I was able to configure and use CNTLM in Windows recently. I encountered a problem during the syncing process of Kindle for PC because of our proxy and installing and configuring CNTLM for Windows fixed that issue for me. Refer to my article for more details.

Tuesday, June 1, 2021
 
aslum
answered 5 Months ago
96

Here is a link to the official Docker documentation for proxy HTTP: https://docs.docker.com/config/daemon/systemd/#httphttps-proxy

A quick outline:

First, create a systemd drop-in directory for the Docker service:

mkdir /etc/systemd/system/docker.service.d

Now create a file called /etc/systemd/system/docker.service.d/http-proxy.conf that adds the HTTP_PROXY environment variable:

[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80/"

If you have internal Docker registries that you need to contact without proxying you can specify them via the NO_PROXY environment variable:

Environment="HTTP_PROXY=http://proxy.example.com:80/"
Environment="NO_PROXY=localhost,127.0.0.0/8,docker-registry.somecorporation.com"

Flush changes:

$ sudo systemctl daemon-reload

Verify that the configuration has been loaded:

$ sudo systemctl show --property Environment docker
Environment=HTTP_PROXY=http://proxy.example.com:80/

Restart Docker:

$ sudo systemctl restart docker
Tuesday, June 1, 2021
 
Student
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :