Proxy and accessing https://<domain>:10000

  • Daworm
  • 09/07/09
  • Offline
Posted: Sun, 2010-02-28 19:24

Due to work configuration on the proxy. I cannot access my domains control panel on https://

How would I go about setting up a proxy on my server that will let me load it still? I plan to lock down the proxy with .htaccess etc.


Actually thinking on this,

  • Daworm
  • 09/07/09
  • Offline
  • Sun, 2010-02-28 19:26

Actually thinking on this, there was a cPanel script to allow this for cPanel servers. You'd just go to cpanel. and it would do it all automatically.

How can I do this with virtualmin?


bump anyone?

  • Daworm
  • 09/07/09
  • Offline
  • Mon, 2010-03-01 20:54

bump

anyone?


Actually. Using my meager

  • Daworm
  • 09/07/09
  • Offline
  • Mon, 2010-03-01 21:20

Actually. Using my meager understanding thought I might look at how to do this. I have a subdomain setup I'm not using atm so just ninja'd the pre-existing subdomain.

As a result here's the (slightly) modified code.

<?php
/* cPanel Proxy 0.4.1
 * http://cpanelproxy.net/
 <em>
 * See README.txt
 *
 */
 
//// Config
 
$version = '0.4.1'; // Please don't change this one. :)
 
// Last part of hostnames (see install instructions)
// Autodetect by removing first element of current hostname
$hostpostfix = preg_replace('/^.</em>?./', '', $<em>SERVER['HTTP_HOST']);
 
// First parts of hostnames
$webmailhost = 'webmail.'.$hostpostfix;
$cpanelhost = 'cpanel.'.$hostpostfix;
$whmhost = 'whm.'.$hostpostfix;
 
// If server is running in CGI-mode HTTP Authentification won't work. If 
// $cgimode is "true", cPanel Proxy will hide HTTP Authentification, forcing 
// cPanel to fall back on Cookie Authentification.
// This means that cPanel Proxy is no longer transparent to the user, as the 
// login-screen will look different than usual.
// Defaults to "true" as it will always works, autodetection may be added 
// later.
$cgimode = true;
 
// The host where cPanel is running. I strongly suggest having this script on 
// the same server as cPanel, and leaving this setting at default "localhost".
$host = 'localhost';
 
// I'm honestly not sure if \r\n or \n is most correct, but in this case it 
// just needs to work.
$nl = "\r\n";
 
//// End of config
 
if ($_SERVER["QUERY_STRING"]=='cPanelProxyVersion') {
  echo '<p><a href="http://cpanelproxy.net/">cPanel Proxy</a> '
    .$version.'</p>';
  exit;
}
 
function error($header, $string) {
  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Error</title>
</head>
<body>
<h1>Error: '.$header.'</h1>
'.$string.'
<hr />
<div style="font-size: 0.8em;"><a href="http://cpanelproxy.net/">'
.'cPanel Proxy '.$version.'</a></div>
</body>
</html>
';
}
 
switch($_SERVER['HTTP_HOST']) {
 case $webmailhost:
   $port = 20000;
   break;
 case $cpanelhost:
   $port = 10000;
   break;
 case $whmhost:
   $port = 2086;
   break;
 default:
   error(
  'Hostname not recognized','<p>Server is misconfigured or you have '
.'entered a wrong address. You can try these in stead:</p>
 
<table>
<tr><td>Webmail: </td><td><a href="http://'.$webmailhost.'/">http://'
.$webmailhost.'/</a></td></tr>
<tr><td>cPanel: </td><td><a href="http://'.$cpanelhost.'/">http://'
.$cpanelhost.'/</a></td></tr>
<tr><td>WHM: </td><td><a href="http://'.$whmhost.'/">http://'.$whmhost
.'/</a></td></tr>
</table>
');
   exit;
}
 
 
//// Get headers from browser
 
// "/webmail" is replaced with "/webmail</em>" in the url, so the server won't
// redirect browsers using this proxy for webmail.
// The protocol is hardcoded to HTTP 1.0. Then we don't have to worry about
// chunked transfers, as 1.1 forces you to.
$frombrowser = $<em>SERVER['REQUEST_METHOD']." "
.str_replace('/webmail</em>', '/webmail',$<em>SERVER['REQUEST_URI'])." "
.'HTTP/1.0'.$nl;
 
 
foreach($_SERVER as $a=>$b) {
  if ($a == 'HTTP_HOST') $b = "$host:$port";
  if ($a == 'HTTP_CONNECTION') $b = "Close"; // FIXME: Maybe a persitent socket could be good for performance. Do we need to make sure only the same browser reuses a socket, or is persistent sockets as stateless as usual?
  if (substr($a,0,5)=='HTTP</em>') {
    $frombrowser .= substr($a,5)
      .': '. $b.$nl;
  }
}
 
// That was the regular headers. Now we need to re-generate the headers that 
// was parsed and thrown away before this script gets a chance to see them.
 
// First authentication.
if (isset($<em>SERVER['PHP_AUTH_USER']) 
    && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
  $frombrowser .= "Authorization: Basic "
.base64_encode($_SERVER['PHP_AUTH_USER'].':'.$_SERVER['PHP_AUTH_PW']).$nl;
}
 
if (strlen(@$_SERVER['CONTENT_TYPE'])) {
  $frombrowser .= "Content-Type: ".$_SERVER['CONTENT_TYPE'].$nl;
}
 
// End of browsers headers (for now).
 
switch($_SERVER['REQUEST_METHOD']) {
 
 case 'HEAD':
 case 'GET':
   // We're done, signalling this with an extra newline.
   $frombrowser .= $nl;
   break;
 
 case 'POST':
   // We probably have a body, we need to include this.
 
   $input = fopen('php://input','r');
   $frombrowser_body = '';
 
   if (strpos(@$_SERVER['CONTENT_TYPE'], 'multipart/form-data')===false) {
 
     // Not multipart/form-data, sending body directly from browser
 
     // First we get the entire post body.
     while (true) {
       $data = fread($input, 10240); // FIXME: Can we optimize here with another buffer-size?
       if (strlen($data)===0) break;
       $frombrowser_body .= $data;
     }
   } else {
 
     // multipart/form-data
 
     $boundary = '--------'.md5(time()); // FIXME: Do we need a better algorithm to generate boundary string?
     $frombrowser .= "Content-Type: multipart/form-data; boundary="
       .$boundary.$nl;
     foreach($_POST as $name=>$data) {
       $frombrowser_body .= '--'.$boundary.$nl
     .'Content-Disposition: form-data; name="'.$name.'"'.$nl
  .$nl.$data.$nl; // FIXME: If $data is an array, handle that correctly.
     }
 
     foreach($_FILES as $name=>$data) {
       if (!is_uploaded_file($data['tmp_name'])) continue;
 
       $frombrowser_body .= '--'.$boundary.$nl
   .'Content-Disposition: form-data; name="'.$name.'";'
     .' filename="'.$data['name'].'"'.$nl; // FIXME: Do we need some kind of encoding here? What if the filename (or the name) has characters like double-quote, colon, semicolon, \n or \r?
       // (Uploading a file with double-quote in filename with Mozilla thru this script fails, I have not done any further testing yet.)
       $frombrowser_body .= 'Content-Type: '.$data['type'].$nl
    .$nl
   .file_get_contents($data['tmp_name'])
    .$nl;
     }
     $frombrowser_body .= '--'.$boundary.$nl;
    }
 
   // Okay, now we can finish the headers and attach the body.
   $frombrowser .= "Content-Length: ".strlen($frombrowser_body).$nl
     .$nl
     .$frombrowser_body;
 
   break;
 
 default:
   error(
     'Method not implemented',
    '<p>Method '.$_SERVER['REQUEST_METHOD'].' not supported in cPanel '
.'Proxy, sorry.</p>'
   );
   exit;
}
 
// Time to contact server and send request
$server = fsockopen($host, $port);
fputs($server, $frombrowser);
 
 
// Get server headers
 
if ($cgimode) {
  $firstline = fgets($server, 10240);
  $array = explode(' ', $firstline);
  $status = (int)$array[1];
  if ($status==401) {
    // Authentication needed, but HTTP authentication doesn't work in CGI-mode.
    header('Status: 200');
  } else {
    header($firstline);
  }
 
}
 
 
while (true) {
  $data = fgets($server, 10240); // FIXME: Can we optimize here with another buffer-size?
  if (strlen(trim($data))==0) break;
 
  // Fix hostname in redirects, cookies...
  $data = str_replace(
       array('localhost:20000', 'localhost:10000', 'localhost:2086'),
       array($webmailhost,      $cpanelhost,     $whmhost),
       $data);
  if (substr($data, 0, 11) == 'Set-Cookie:') {
    $data = str_replace(
            '; domain=localhost', 
           '; domain='.$_SERVER['HTTP_HOST'], 
            $data);
  }
 
  header($data, false);
}
 
if($_SERVER['REQUEST_METHOD']=='HEAD') {
  exit;
}
 
// Get server body
$data = '';
while (true) {
  $line = fgets($server, 10240); // FIXME: Can we optimize here with another buffer-size?
 
  if (strlen($line)===0) break;
  // A line will never be completely empty, as it will end with a "newline". 
  // So if we get a completely empty line, there's no more data.
 
  if ($cgimode) {
    // Let's hide that ugly message. It's not the browser that doesn't support 
    // HTTP-Auth, it's CGI...
    $line = str_replace('If your browser does not support HTTP '
           .'Authentication, please use this form:','',$line);
  }
 
  // Fix hostname 
  $line = str_replace(
       array('localhost:20000', 'localhost:10000', 'localhost:2086'),
       array($webmailhost,      $cpanelhost,     $whmhost),
       $line);
 
  $data .= preg_replace('</em>(\'|"|=)/webmail_', '$1/webmail_', $line);
  // This has heavy influence on chunk-size (for HTTP/1.1 to browser)
  if (strlen($data)>10240) { // FIXME: Can we optimize here with another buffer-size?
    echo $data;
    flush();
    $data = '';
  }
}
// $data is probably not empty.
echo $data;
?>

Problem is it's still calling "http://:10000/" somewhere and I can't quite make sense on how to make it work on https://:10000/

Pointers?

EDIT:

I am aware that the cpanel proxy prob won't even work for this out of the box... but. The fact I get a message saying "server is running in SSL Secure mode" when I access "https://hosting./" means... it is working to a degree.


Howdy, You should also be

  • andreychek
  • 01/04/09
  • Online Now
  • Mon, 2010-03-01 21:37

Howdy,

You should also be able to setup a proxy within Virtualmin to do that... if you go into Server Configuration -> Edit Proxy Website, you should be able to proxy that particular Virtual Server to forward to Virtualmin.

That is, if you setup a Virtual Server named vm.example.com, and tell it to proxy connections to https://your_domain.com:10000, that should do what you're after.

-Eric


Hurm - that seems more

  • Daworm
  • 09/07/09
  • Offline
  • Mon, 2010-03-01 22:22

Hurm - that seems more simple... :)

I'll have to do that tonight (can't get into SSL at work >.< )


Hurm - just did the change

  • Daworm
  • 09/07/09
  • Offline
  • Mon, 2010-03-01 23:45

Hurm - just did the change via my mobile and accessed it.

I get this

Error - No cookies
 
Your browser does not support cookies, which are required for this web server to work in session authentication mode
edit: ahh - redid as https:// and it worked.

AWESOME! thanks :)


I now get this when i try to

  • Daworm
  • 09/07/09
  • Offline
  • Tue, 2010-03-02 00:43

I now get this when i try to go and edit the proxy config settings for another domain.

Security Warning     
Warning! Webmin has detected that the program https://<domain>:10000/virtual-server/proxy_form.cgi?dom=125887368685941& was linked to from the URL https://webmin.<domain>/left.cgi?mode=virtualmin&dom=125887368685941, which appears to be outside the Webmin server. This may be an attempt to trick your server into executing a dangerous command.
 
If this is a legitimate link, you can allow links from this URL as follows :
 
    * Login to Webmin normally.
    * Go to the Webmin Configuration module.
    * Click on the Trusted Referrers icon.
    * Enter the hostname <domain> into the Trusted websites field, and click Save.
 
Alternately, you can configure Webmin to allow this link from the command line by :
 
    * Login as root, and edit the /etc/webmin/config file.
    * Add the line referers=<domain> at the end, or if a referers line already exists add <domain> to it.
    * Save the file.

I have done as above and restarted httpd / webmin and still get the same message...


Hurm - I edited the /config

  • Daworm
  • 09/07/09
  • Offline
  • Tue, 2010-03-02 21:12

Hurm - I edited the /config file and set referrers=1 and now it works.

Strange.