<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>秋天的博客 &#187; 主机管理</title>
	<atom:link href="http://www.fallday.org/archives/category/managemet/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fallday.org</link>
	<description>虚拟主机/VPS/云计算实践</description>
	<lastBuildDate>Sat, 21 Jan 2012 03:21:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Linux下用curlftpfs挂载FTP服务器 [CentOS][转]</title>
		<link>http://www.fallday.org/archives/763</link>
		<comments>http://www.fallday.org/archives/763#comments</comments>
		<pubDate>Sat, 21 Jan 2012 03:18:15 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[curlftpfs]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[fuse]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=763</guid>
		<description><![CDATA[A、安装curlftpfs A.1、安装DAG repository Fedora可以直接yum install curlftpfs，CentOS不行，得用DAG repository，所以得先安装DAG repository。 rpm -Uhv http://apt.sw.be/RedHat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm A.2、安装 curlftpfs yum install curlftpfs B、挂载FTP服务器 B.1、用curlftpfs命令挂载 curlftpfs -o codepage=utf8 ftp://username:password@192.168.192.168 /ftp codepage：      编码 username：      FTP用户名 password:       FTP密码 192.168.1.111:  FTP地址 /ftp:           准备挂载到的路径 B.2、卸载挂载 fusermount -u /ftp 或 umount /ftp B.3、开放权限 这样其它用户也能读写了,uid和gid改成你自己的id sudo curlftpfs –o rw,allow_other,uid=0,gid=0 ftp:// username: password @192.168.1.111 /ftp B.4、开机自动挂载 echo “curlftpfs#username:password@192.168.1.111 /ftp [...]]]></description>
			<content:encoded><![CDATA[<p>A、安装curlftpfs</p>
<p>A.1、安装DAG repository</p>
<p><a title="Fedora" href="http://www.linuxidc.com/topicnews.aspx?tid=5">Fedora</a>可以直接yum install curlftpfs，CentOS不行，得用DAG repository，所以得先安装DAG repository。</p>
<p>rpm -Uhv http://apt.sw.be/<a title="RedHat" href="http://www.linuxidc.com/topicnews.aspx?tid=10">RedHat</a>/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm</p>
<p>A.2、安装 curlftpfs</p>
<p>yum install curlftpfs</p>
<p><span id="more-763"></span>B、挂载FTP服务器</p>
<p>B.1、用curlftpfs命令挂载</p>
<p>curlftpfs -o codepage=utf8 ftp://username:password@192.168.192.168 /ftp</p>
<p>codepage：      编码</p>
<p>username：      FTP用户名</p>
<p>password:       FTP密码<br />
192.168.1.111:  FTP地址<br />
/ftp:           准备挂载到的路径</p>
<p>B.2、卸载挂载</p>
<p>fusermount -u /ftp</p>
<p>或</p>
<p>umount /ftp</p>
<p>B.3、开放权限</p>
<p>这样其它用户也能读写了,uid和gid改成你自己的id</p>
<p>sudo curlftpfs –o rw,allow_other,uid=0,gid=0 ftp:// username: password @192.168.1.111 /ftp</p>
<p>B.4、开机自动挂载<br />
echo “curlftpfs#username:password@192.168.1.111 /ftp fuse allow_other,uid=0,gid=0 0 0&#8243; &gt;&gt; /etc/fstab</p>
<p>原文链接: http://www.linuxidc.com/Linux/2011-05/35917.htm</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/763/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WHMCS自动VPN开通</title>
		<link>http://www.fallday.org/archives/756</link>
		<comments>http://www.fallday.org/archives/756#comments</comments>
		<pubDate>Thu, 19 Jan 2012 14:59:43 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[FreeRadius]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[WHMCS]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=756</guid>
		<description><![CDATA[前段时间试用WHMCS时，也试着做了一个VPN自动销售自动开通的模块。VPN基于FreeRadius认证。 1. provide restsql interface on radius db 1. install restsql insto /radius/restsql http://phprestsql.sourceforge.net/download.html http://phprestsql.sourceforge.net/ 1a. .htaccess RewriteEngine On RewriteBase /radius/restsql RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.*$ index.php 1b. phprestsql.ini [settings] baseURL = "/radius/restsql" [database] type = "mysql" ;type = "postgresql" server = "localhost" database = "radius" username = "radius" password = "xxxxxx" [...]]]></description>
			<content:encoded><![CDATA[<p>前段时间试用WHMCS时，也试着做了一个VPN自动销售自动开通的模块。VPN基于FreeRadius认证。</p>
<p>1. provide restsql interface on radius db</p>
<p>1.  install restsql insto /radius/restsql</p>
<p>http://phprestsql.sourceforge.net/download.html</p>
<p>http://phprestsql.sourceforge.net/</p>
<p>1a. .htaccess</p>
<pre>
	RewriteEngine On
	RewriteBase /radius/restsql
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^.*$ index.php
</pre>
<p><span id="more-756"></span>1b. phprestsql.ini</p>
<pre>
[settings]
	baseURL = "/radius/restsql"

	[database]
	type = "mysql"
	;type = "postgresql"
	server = "localhost"
	database = "radius"
	username = "radius"
	password = "xxxxxx"
	;foreignKeyPostfix = "_uid"

	[renderers]
	text/xml = xml.php
	text/plain = plain.php
	text/html = html.php

	[mimetypes]
	xml = text/xml
	txt = text/plain
</pre>
<p>1c. phprestsql.php</p>
<pre>
	#function parseRequestData
	$parts = explode('=', $pair, 2);
	#function PHPRestSQL
	/*
				$lastPart = array_pop($urlParts);
				$dotPosition = strpos($lastPart, '.');
				if ($dotPosition !== FALSE) {
					$this->extension = substr($lastPart, $dotPosition + 1);
					$lastPart = substr($lastPart, 0, $dotPosition);
				}
				array_push($urlParts, $lastPart);
	*/
</pre>
<p>1d. change primary key of usercheck, usergroup to username</p>
<p>2. WHMCS freeraidus server module</p>
<pre>
<?php
function freeradius_ConfigOptions() {

	# Should return an array of the module options for each product - maximum of 24

    $configarray = array(
	 "Monthly Traffic Quota" => array( "Type" => "text", "Size" => "10", "Description" => "MB" )
	);

	return $configarray;

}

function freeradius_CreateAccount($params) {

    # ** The variables listed below are passed into all module functions **

    $serviceid = $params["serviceid"]; # Unique ID of the product/service in the WHMCS Database
    $pid = $params["pid"]; # Product/Service ID
    $producttype = $params["producttype"]; # Product Type: hostingaccount, reselleraccount, server or other
    $domain = $params["domain"];
	$params["username"] = $params["clientsdetails"]["email"];
	$username = $params["username"];
	$password = $params["password"];
    $clientsdetails = $params["clientsdetails"]; # Array of clients details - firstname, lastname, email, country, etc...
    $customfields = $params["customfields"]; # Array of custom field values for the product
    $configoptions = $params["configoptions"]; # Array of configurable option values for the product

    # Product module option settings from ConfigOptions array above
    $configoption1 = $params["configoption1"];

    # Additional variables if the product/service is linked to a server
    $server = $params["server"]; # True if linked to a server
    $serverid = $params["serverid"];
    $serverip = $params["serverip"];
    $serverusername = $params["serverusername"];
    $serverpassword = $params["serverpassword"];
    $serveraccesshash = $params["serveraccesshash"];
    $serversecure = $params["serversecure"]; # If set, SSL Mode is enabled in the server config

 $url = "http://" .$serverip ."/radius/restsql/radcheck"; # URL to WHMCS API file

 $postfields["username"] = $clientsdetails["email"];
 $postfields["attribute"] = "Cleartext-Password";
 $postfields["op"] = ":="; #action performed by the [[API:Functions]]
 $postfields["value"] = $password;

 $query_string = "";
 foreach ($postfields as $k=>$v) $query_string .= $k ."=" .$v ."\n";

 $successful = True;

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 curl_setopt($ch, CURLOPT_USERPWD, $serverusername .":" .$serverpassword);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
 $data = curl_exec($ch);
 if (curl_error($ch)) {
	 $successful = False;
	 $result = "Error Message(user): " .curl_errno($ch) ."- " .curl_error($ch);
 } else {
	 $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	 if ( $ret != 201 ) {
		$successful = False;
		$result = "HTTP Return Code(user): " .$ret;
	 }
 }
 curl_close($ch);

if ( $successful ) {
 $url = "http://" .$serverip ."/radius/restsql/radusergroup"; # URL to WHMCS API file

 unset($postfields);
 $postfields["username"] = $clientsdetails["email"];
 $postfields["groupname"] = "VIP";

 $query_string = "";
 foreach ($postfields as $k=>$v) $query_string .= $k ."=" .$v ."\n";

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 curl_setopt($ch, CURLOPT_USERPWD, $serverusername .":" .$serverpassword);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
 $data = curl_exec($ch);
 if (curl_error($ch)) {
	 $successful = False;
	 $result = "Error Message(usergroup): " .curl_errno($ch) ."- " .curl_error($ch);
 } else {
	 $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	 if ( $ret != 201 ) {
		$successful = False;
		$result = "HTTP Return Code(usergroup): " .$ret;
	 }
 }
 curl_close($ch);
}
	if ($successful) {
		$result = "success";
	}
	return $result;

}

function freeradius_TerminateAccount($params) {

    $serviceid = $params["serviceid"]; # Unique ID of the product/service in the WHMCS Database
    $pid = $params["pid"]; # Product/Service ID
    $producttype = $params["producttype"]; # Product Type: hostingaccount, reselleraccount, server or other
    $domain = $params["domain"];
	$params["username"] = $params["clientsdetails"]["email"];
	$username = $params["username"];
	$password = $params["password"];
    $clientsdetails = $params["clientsdetails"]; # Array of clients details - firstname, lastname, email, country, etc...
    $customfields = $params["customfields"]; # Array of custom field values for the product
    $configoptions = $params["configoptions"]; # Array of configurable option values for the product

    # Product module option settings from ConfigOptions array above
    $configoption1 = $params["configoption1"];

    # Additional variables if the product/service is linked to a server
    $server = $params["server"]; # True if linked to a server
    $serverid = $params["serverid"];
    $serverip = $params["serverip"];
    $serverusername = $params["serverusername"];
    $serverpassword = $params["serverpassword"];
    $serveraccesshash = $params["serveraccesshash"];
    $serversecure = $params["serversecure"]; # If set, SSL Mode is enabled in the server config

 $url = "http://" .$serverip ."/radius/restsql/radcheck/" .$clientsdetails["email"]; # URL to WHMCS API file

 $successful = True;

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 curl_setopt($ch, CURLOPT_USERPWD, $serverusername .":" .$serverpassword);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $data = curl_exec($ch);
 if (curl_error($ch)) {
	 $successful = False;
	 $result = "Error Message(user): " .curl_errno($ch) ."- " .curl_error($ch);
 } else {
	 $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	 if ( $ret != 204 ) {
		$successful = False;
		$result = "HTTP Return Code(user): " .$ret;
	 }
 }
 curl_close($ch);

 $url = "http://" .$serverip ."/radius/restsql/radusergroup/" .$clientsdetails["email"]; # URL to WHMCS API file

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 curl_setopt($ch, CURLOPT_USERPWD, $serverusername .":" .$serverpassword);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $data = curl_exec($ch);
 if (curl_error($ch)) {
	 $successful = False;
	 $result = "Error Message(usergroup): " .curl_errno($ch) ."- " .curl_error($ch);
 } else {
	 $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	 if ( $ret != 204 ) {
		$successful = False;
		$result = "HTTP Return Code(usergroup): " .$ret;
	 }
 }
 curl_close($ch);

    if ($successful) {
		$result = "success";
	}
	return $result;
}

function freeradius_SuspendAccount($params) {

	# Code to perform action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_UnsuspendAccount($params) {

	# Code to perform action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_ChangePassword($params) {

	# Code to perform action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_ChangePackage($params) {

	# Code to perform action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_ClientArea($params) {

	$username = $params["clientsdetails"]["email"];
	$password = $params["password"];
    $clientdetails = $params["clientdetails"];
	$server = $params["server"]; # True if linked to a server
    $serverid = $params["serverid"];
    $serverip = $params["serverip"];
    $serverusername = $params["serverusername"];
    $serverpassword = $params["serverpassword"];
    $serveraccesshash = $params["serveraccesshash"];
    $serversecure = $params["serversecure"]; # If set, SSL Mode is enabled in the server config

 $url = "http://" .$serverip ."/radius/usage_check.php3?login=" .$username; # URL to WHMCS API file

 $successful = True;

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_GET, 1);
 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 curl_setopt($ch, CURLOPT_USERPWD, $serverusername .":" .$serverpassword);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $data = curl_exec($ch);
 if (curl_error($ch)) {
	 $successful = False;
	 $result = "Error Message(user): " .curl_errno($ch) ."- " .curl_error($ch);
 } else {
	 $ret = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	 if ( $ret != 200 ) {
		$successful = False;
		$result = "HTTP Return Code(user): " .$ret;
	 }
 }
 curl_close($ch);

 if ( $successful ) {
	$code = $data;
 } else {
	 $code = $result;
 }
	return $code;

}

function freeradius_AdminLink($params) {

	$code = '';
	return $code;

}

function freeradius_LoginLink($params) {

	echo "";

}

function freeradius_reboot($params) {

	# Code to perform reboot action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_shutdown($params) {

	# Code to perform shutdown action goes here...

    if ($successful) {
		$result = "success";
	} else {
		$result = "Error Message Goes Here...";
	}
	return $result;

}

function freeradius_ClientAreaCustomButtonArray() {
    $buttonarray = array(
	 "Reboot Server" => "reboot",
	);
	return $buttonarray;
}

function freeradius_AdminCustomButtonArray() {
    $buttonarray = array(
	 "Reboot Server" => "reboot",
	 "Shutdown Server" => "shutdown",
	);
	return $buttonarray;
}

function freeradius_extrapage($params) {
    $pagearray = array(
     'freeradiusfile' => 'example',
     'breadcrumb' => ' > <a href="#">Example Page</a>',
     'vars' => array(
        'var1' => 'demo1',
        'var2' => 'demo2',
     ),
    );
	return $pagearray;
}

function freeradius_UsageUpdate($params) {

	$serverid = $params['serverid'];
	$serverhostname = $params['serverhostname'];
	$serverip = $params['serverip'];
	$serverusername = $params['serverusername'];
	$serverpassword = $params['serverpassword'];
	$serveraccesshash = $params['serveraccesshash'];
	$serversecure = $params['serversecure'];

	# Run connection to retrieve usage for all domains/accounts on $serverid

	# Now loop through results and update DB

	foreach ($results AS $domain=>$values) {
        update_query("tblhosting",array(
         "diskused"=>$values['diskusage'],
         "dislimit"=>$values['disklimit'],
         "bwused"=>$values['bwusage'],
         "bwlimit"=>$values['bwlimit'],
         "lastupdate"=>"now()",
        ),array("server"=>$serverid,"domain"=>$values['domain']));
    }

}

function freeradius_AdminServicesTabFields($params) {

    $result = select_query("mod_customtable","",array("serviceid"=>$params['serviceid']));
    $data = mysql_fetch_array($result);
    $var1 = $data['var1'];
    $var2 = $data['var2'];
    $var3 = $data['var3'];
    $var4 = $data['var4'];

    $fieldsarray = array(
     'Field 1' => '
<input type="text" name="modulefields[0]" size="30" value="'.$var1.'" />',
     'Field 2' => '
<select name="modulefields[1]">
<option>Val1</option</select>

',
     'Field 3' => '<textarea name="modulefields[2]" rows="2" cols="80">'.$var3.'</textarea>',
     'Field 4' => $var4, # Info Output Only
    );
    return $fieldsarray;

}

function freeradius_AdminServicesTabFieldsSave($params) {
    update_query("mod_customtable",array(
        "var1"=>$_POST['modulefields'][0],
        "var2"=>$_POST['modulefields'][1],
        "var3"=>$_POST['modulefields'][2],
    ),array("serviceid"=>$params['serviceid']));
}
?>
</pre>
<p>3. Customized VPN usage page in clientarea<br />
3a. usage_check.php3 (based on user_admin.php3)</p>
<pre>
<?php
require('../conf/config.php3');
?>
<?php
require('../lib/functions.php3');
require('../lib/defaults.php3');
$date = strftime('%A, %e %B %Y, %T %Z');

if (is_file("../lib/$config[general_lib_type]/user_info.php3")){
	include("../lib/$config[general_lib_type]/user_info.php3");
	if ($user_exists == 'no'){
		exit();
	}
}

if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
	include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
else{
	exit();
}

$monthly_limit = ($item_vals['Max-Monthly-Session'][0] != '') ? $item_vals['Max-Monthly-Session'][0] : $default_vals['Max-Monthly-Session'][0];
$monthly_limit = ($monthly_limit) ? $monthly_limit : $config[counter_default_monthly];
$daily_limit = ($item_vals['Max-Daily-Session'][0] != '') ? $item_vals['Max-Daily-Session'][0] : $default_vals['Max-Daily-Session'][0];
$daily_limit = ($daily_limit) ? $daily_limit : $config[counter_default_daily];
$monthly_traffic_limit = ($item_vals['Max-Monthly-Traffic'][0] != '') ? $item_vals['Max-Monthly-Traffic'][0] : $default_vals['Max-Monthly-Traffic'][0];
$monthly_traffic_limit = ($monthly_traffic_limit) ? $monthly_traffic_limit * 1024 : $config[counter_default_monthly_traffic];
$remaining = 'unlimited time';
$log_color = 'green';

$now = time();
$week = $now - 604800;
$now_str = date("$config[sql_date_format]",$now + 86400);
$week_str = date("$config[sql_date_format]",$week);
$day = date('w');
$week_start = date($config[sql_date_format],$now - ($day)*86400);
$month_start = date($config[sql_date_format],$now - date('j')*86400);
$today = $day;
$now_tmp = $now;
for ($i = $day; $i >-1; $i--){
	$days[$i] = date($config[sql_date_format],$now_tmp);
	$now_tmp -= 86400;
}
$day++;
//$now -= ($day * 86400);
$now -= 604800;
$now += 86400;
for ($i = $day; $i <= 6; $i++){
	$days[$i] = date($config[sql_date_format],$now);
//	$now -= 86400;
	$now += 86400;
}

$daily_used = $weekly_used = $monthly_used = $lastlog_session_time = '-';
$extra_msg = '';
$used = array('-','-','-','-','-','-','-');

$link = @da_sql_pconnect($config);
if ($link){
	if ($monthly_limit != 'none' || $config[counter_monthly_calculate_usage] == 'true'){
		$search = @da_sql_query($link,$config,
		"SELECT sum(acctsessiontime) AS sum_sess_time FROM $config[sql_accounting_table] WHERE username = '$login'
		AND acctstarttime >= '$month_start' AND acctstarttime <= '$now_str';");
		if ($search){
			$row = @da_sql_fetch_array($search,$config);
			$monthly_used = $row[sum_sess_time];
		}
		else
			echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b>\n";
	}
	if ($monthly_traffic_limit != 'none' || $config[counter_monthly_calculate_usage] == 'true'){
		$search = @da_sql_query($link,$config,
		"SELECT sum(acctinputoctets + acctoutputoctets) AS sum_sess_traffic FROM $config[sql_accounting_table] WHERE username = '$login'
		AND acctstarttime >= '$month_start' AND acctstarttime <= '$now_str';");
		if ($search){
			$row = @da_sql_fetch_array($search,$config);
			$monthly_traffic_used = $row[sum_sess_traffic];
		}
		else
			echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b>\n";
	}
	$search = @da_sql_query($link,$config,
	"SELECT COUNT(*) AS counter FROM $config[sql_accounting_table] WHERE username = '$login'
	AND acctstoptime >= '$week_str' AND acctstoptime <= '$now_str'
	AND (acctterminatecause LIKE 'Login-Incorrect%' OR
	acctterminatecause LIKE 'Invalid-User%' OR
	acctterminatecause LIKE 'Multiple-Logins%');");
	if ($search){
		$row = @da_sql_fetch_array($search,$config);
		$tot_badlogins = $row[counter];
	}
	else
		echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b>\n";
	for($i = 0; $i <=6; $i++){
		if ($days[$i] == '')
			continue;
		$search = @da_sql_query($link,$config,
		"SELECT sum(acctsessiontime) AS sum_sess_time FROM $config[sql_accounting_table] WHERE
		username = '$login' AND acctstoptime >= '$days[$i] 00:00:00'
		AND acctstoptime <= '$days[$i] 23:59:59';");
		if ($search){
			$row = @da_sql_fetch_array($search,$config);
			$used[$i] = $row[sum_sess_time];
			if ($daily_limit != 'none' &#038;&#038; $used[$i] > $daily_limit)
				$used[$i] = "<font color=red>" . time2str($used[$i]) . "</font>";
			else
				$used[$i] = time2str($used[$i]);
			if ($today == $i){
				$daily_used = $row[sum_sess_time];
				if ($daily_limit != 'none'){
					$remaining = $daily_limit - $daily_used;
					if ($remaining <=0)
						$remaining = 0;
					$log_color = ($remaining) ? 'green' : 'red';
					if (!$remaining)
						$extra_msg = '(Out of daily quota)';
				}
				$daily_used = time2str($daily_used);
				if ($daily_limit != 'none' &#038;&#038; !$remaining)
					$daily_used = "<font color=red>$daily_used</font>";
			}
		}
		else
			echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b>\n";
	}
	if ($monthly_limit != 'none'){
		$tmp = $monthly_limit - $monthly_used;
		if ($tmp <=0){
			$tmp = 0;
			$extra_msg .= '(Out of monthly quota)';
		}
		if (!is_numeric($remaining))
			$remaining = $tmp;
		if ($remaining > $tmp)
			$remaining = $tmp;
		$log_color = ($remaining) ? 'green' : 'red';
	}
	if ($monthly_limit != 'none' || $config[counter_monthly_calculate_usage] == 'true'){
		$monthly_used = time2str($monthly_used);
		if ($monthly_limit != 'none' &#038;&#038; !$tmp)
			$monthly_used = "<font color=red>$monthly_used</font>";
	}
	if ($monthly_traffic_limit != 'none'){
		$tmp = $monthly_traffic_limit - $monthly_traffic_used;
		if ($tmp <=0){
			$tmp = 0;
			$extra_msg .= '(Out of monthly traffic quota)';
		}
	}
	if ($monthly_traffic_limit != 'none' || $config[counter_monthly_calculate_usage] == 'true'){
		$monthly_traffic_used = bytes2str($monthly_traffic_used);
		if ($monthly_traffic_limit != 'none' &#038;&#038; !$tmp)
			$monthly_traffic_used = "<font color=red>$monthly_traffic_used</font>";
	}
}
else
	echo "<b>Could not connect to SQL database</b>\n";

$monthly_traffic_limit = (is_numeric($monthly_traffic_limit)) ? bytes2str($monthly_traffic_limit) : $monthly_traffic_limit;
$monthly_limit = (is_numeric($monthly_limit)) ? time2str($monthly_limit) : $monthly_limit;
$weekly_limit = (is_numeric($weekly_limit)) ? time2str($weekly_limit) : $weekly_limit;
$daily_limit = (is_numeric($daily_limit)) ? time2str($daily_limit) : $daily_limit;
$session_limit = (is_numeric($session_limit)) ? time2str($session_limit) : $session_limit;
$remaining = (is_numeric($remaining)) ? time2str($remaining) : $remaining;

if ($item_vals['Dialup-Access'][0] == 'FALSE' || (!isset($item_vals['Dialup-Access'][0]) &#038;&#038; $attrmap['Dialup-Access'] != '' &#038;&#038; $attrmap['Dialup-Access'] != 'none'))
	$msg =<<<EON
<font color=red><b> The user account is locked </b></font>
EON;
else
	$msg =<<<EON
user can login for <font color="$log_color"> <b>$remaining $extra_msg</font>
EON;
$lock_msg = $item_vals['Dialup-Lock-Msg'][0];
if ($lock_msg != '')
	$descr =<<<EON
<font color=red><b>$lock_msg </b</font>
EON;
else
	$descr = '-';

$expiration = $default_vals['Expiration'][0];
if ($item_vals['Expiration'][0] != '')
	$expiration = $item_vals['Expiration'][0];
if ($expiration != ''){
	$expiration = strtotime($expiration);
	if ($expiration != -1 &#038;&#038; $expiration < time())
		$descr = <<<EOM
<font color=red><b>User Account has expired</b></font>
EOM;
}

require('../html/usage_check.html.php3');
?>
</pre>
<p>3b. usage_check.html.php3</p>
<pre>
<?php
echo <<<EOM
<table border=0 width=640 cellpadding=1 cellspacing=1>
<tr valign=top>
<td width=340></td>
<td bgcolor="black" width=250>
<table border=0 width=100% cellpadding=2 cellspacing=0>
<tr bgcolor="#907030" align=right valign=top>
<th>
	<font color="white">使用统计</font>&nbsp;
	</th>
</tr>
</table>
</td>
</tr>
<tr bgcolor="black" valign=top>
<td colspan=2>
<table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
<tr>
<td>
<table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
<tr>
<td align=center bgcolor="#d0ddb0">-</td>
<td align=center bgcolor="#d0ddb0"><b>本月流量统计</b></td>
<td align=center bgcolor="#d0ddb0"><b>本月使用时长</b></td>
<td align=center bgcolor="#d0ddb0"><b>今天使用时长</b></td>
</tr>
<tr>
<td align=center bgcolor="#d0ddb0"><b>最大限额</b></td>
<td>$monthly_traffic_limit</td>
<td>$monthly_limit</td>
<td>$daily_limit</td>
</tr>
<tr>
<td align=center bgcolor="#d0ddb0"><b>已经使用</b></td>
<td>$monthly_traffic_used</td>
<td>$monthly_used</td>
<td>$daily_used</td>
</tr>
</table>
</table>
</table>


EOM;
?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/756/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL双向同步</title>
		<link>http://www.fallday.org/archives/752</link>
		<comments>http://www.fallday.org/archives/752#comments</comments>
		<pubDate>Thu, 19 Jan 2012 14:49:36 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[数据同步]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=752</guid>
		<description><![CDATA[MySql双向同步的配置整理。 1. Master [mysqld] datadir=/home/mysql socket=/home/mysql/mysql.sock user=mysql # skip-bdb # skip-innodb # skip-networking symbolic-links=0 #bind-address=127.0.0.1 #innodb_file_per_table=1 sync_binlog=1 server-id=4256076 log-bin=mysql-bin log-error=mysql-bin.err binlog_do_db=blog binlog_do_db=kids binlog_do_db=radius binlog_do_db=zenp binlog_ignore_db=mysql report-host=mail.myvm.net relay-log=mysqld-relay-bin master-host=176.34.57.108 master-user=mybackup master-pass=aq1SW2de master-port=3306 master-connect-retry=60 replicate-do-db=radius replicate-do-db=blog replicate-do-db=kids replicate-do-db=zenp replicate-ignore-db=mysql slave-skip-errors=all 2. Slave [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [...]]]></description>
			<content:encoded><![CDATA[<p>MySql双向同步的配置整理。</p>
<p>1. Master<br />
[mysqld]<br />
datadir=/home/mysql<br />
socket=/home/mysql/mysql.sock<br />
user=mysql</p>
<p># skip-bdb<br />
# skip-innodb<br />
# skip-networking<br />
symbolic-links=0<br />
#bind-address=127.0.0.1<br />
#innodb_file_per_table=1</p>
<p><span id="more-752"></span>sync_binlog=1</p>
<p>server-id=4256076<br />
log-bin=mysql-bin<br />
log-error=mysql-bin.err<br />
binlog_do_db=blog<br />
binlog_do_db=kids<br />
binlog_do_db=radius<br />
binlog_do_db=zenp<br />
binlog_ignore_db=mysql<br />
report-host=mail.myvm.net<br />
relay-log=mysqld-relay-bin<br />
master-host=176.34.57.108<br />
master-user=mybackup<br />
master-pass=aq1SW2de<br />
master-port=3306<br />
master-connect-retry=60<br />
replicate-do-db=radius<br />
replicate-do-db=blog<br />
replicate-do-db=kids<br />
replicate-do-db=zenp<br />
replicate-ignore-db=mysql<br />
slave-skip-errors=all</p>
<p>2. Slave<br />
[mysqld]<br />
datadir=/var/lib/mysql<br />
socket=/var/lib/mysql/mysql.sock<br />
user=mysql<br />
# Disabling symbolic-links is recommended to prevent assorted security risks<br />
symbolic-links=0<br />
server-id=1325430036<br />
report-host=ec2.myvm.net<br />
relay-log=mysqld-relay-bin-new<br />
master-host=106.187.34.155<br />
master-user=mybackup<br />
master-pass=aq1SW2de<br />
master-port=3306<br />
master-connect-retry=60<br />
replicate-do-db=radius<br />
replicate-do-db=blog<br />
replicate-do-db=kids<br />
replicate-do-db=zenp<br />
replicate-ignore-db=mysql<br />
sync_binlog=1<br />
log-bin=mysql-bin<br />
log-error=mysql-bin.err<br />
binlog_do_db=blog<br />
binlog_do_db=kids<br />
binlog_do_db=radius<br />
binlog_do_db=zenp<br />
binlog_ignore_db=mysql<br />
slave-skip-errors=all</p>
<p>3. Key Point<br />
FLUSH TABLES WITH READ LOCK;<br />
backup master da and restore in slave<br />
UNLOCK TABLES;</p>
<p>4. Sample<br />
 # 查看 A 服务器主机状态（记录二进制开始文件，位置）<br />
 SHOW MASTER STATUS;</p>
<p># B 服务器锁表（锁表状态下不能终止mysql进程，否则会失败）<br />
 FLUSH TABLES WITH READ LOCK;</p>
<p># 修改 B 服务器配置<br />
 CHANGE MASTER TO MASTER_HOST=’192.168.1.100′,MASTER_USER=’backup’, MASTER_PASSWORD=’123′,MASTER_LOG_FILE=’binlog.000001′,MASTER_LOG_POS=107;</p>
<p># 开启 B 服务器同步进程<br />
 START SLAVE;</p>
<p># 查看 B 服务器同步状态是否正常<br />
 SHOW SLAVE STATUS;</p>
<p># 查看 B 服务器主机（记录二进制开始文件，位置）<br />
 SHOW MASTER STATUS;</p>
<p># 修改 A 服务器配置<br />
 CHANGE MASTER TO MASTER_HOST=’192.168.1.101′,MASTER_USER=’backup’,MASTER_PASSWORD=’123′,MASTER_LOG_FILE=’binlog.000001′,MASTER_LOG_POS=107;</p>
<p># 开启 A 服务器同步进程<br />
 START SLAVE;</p>
<p># 分别查看 A B 服务器同步状态，确定是否成功<br />
 SHOW SLAVE STATUS;SHOW MASTER STATUS;</p>
<p># 解锁 A B 服务器<br />
 UNLOCK TABLES;</p>
<p>5. Reference:</p>
<p>http://database.51cto.com/art/201005/201636.htm</p>
<p>http://www.2cto.com/database/201108/99584.html</p>
<p>http://www.aixchina.net/club/viewthread.php?tid=26916</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/752/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeRadius安装配置整理</title>
		<link>http://www.fallday.org/archives/750</link>
		<comments>http://www.fallday.org/archives/750#comments</comments>
		<pubDate>Thu, 19 Jan 2012 14:46:26 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[FreeRadius]]></category>
		<category><![CDATA[IPSec]]></category>
		<category><![CDATA[L2TP]]></category>
		<category><![CDATA[PPTP]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=750</guid>
		<description><![CDATA[利用Amazon的EC2实例，以整理了一下FreeRadius的安装配置。 1. yum install freeradius freeradius-mysql freeradius-utils 2. local test 2a. vi /etc/raddb/users to uncomment the section of steve Cleartext-Password := “testing” 2b. vi /etc/raddb/clients.conf, change the the ipaddr of client localhost to the local eth0 interface ipaddr = 10.150.186.120 2c. run radius in debug mode usr/local/sbin/radiusd -X 2d. run radtest, “Access-Accept packet” stand for [...]]]></description>
			<content:encoded><![CDATA[<p>利用Amazon的EC2实例，以整理了一下FreeRadius的安装配置。</p>
<p>1.  yum install freeradius freeradius-mysql freeradius-utils</p>
<p>2.  local test<br />
2a. vi /etc/raddb/users to uncomment the section of<br />
	steve Cleartext-Password := “testing”<br />
2b. vi /etc/raddb/clients.conf, change the the ipaddr of client localhost to the local eth0 interface<br />
	ipaddr = 10.150.186.120<br />
2c. run radius in debug mode<br />
	usr/local/sbin/radiusd -X<br />
2d. run radtest, “Access-Accept packet” stand for success，”Access-Reject” stand for failure<br />
	/usr/local/bin/radtest steve testing localhost 0 testing123</p>
<p><span id="more-750"></span>3.  Enable mysql module<br />
3a. 启用MySQL模块支持<br />
	vim /etc/raddb/radiusd.conf<br />
	# 查找”sql.conf”(683行)，去掉#号<br />
	#找到$INCLUDE sql/mysql/counter.conf，去掉前面的#。<br />
3b. 创建 radius 数据库及表<br />
	# 123456是你mysql的root密码<br />
	mysqladmin -uroot -p123456 create radius;</p>
<p>	#修改radius帐号的密码<br />
	cd /etc/raddb/sql/mysql<br />
	sed -i &#8216;s/radpass/123456/g&#8217; admin.sql<br />
	sed -i &#8216;s/radpass/123456/g&#8217; /etc/raddb/sql.conf</p>
<p>	mysql -uroot -p123456 < admin.sql<br />
	mysql -uroot -p123456 radius < ippool.sql<br />
	mysql -uroot -p123456 radius < schema.sql<br />
	mysql -uroot -p123456 radius < wimax.sql<br />
	mysql -uroot -p123456 radius < cui.sql<br />
	mysql -uroot -p123456 radius < nas.sql<br />
3.c  打开从数据库查询nas支持. 默认从 “/etc/raddb/clients.conf” 文件读取，开启后可从数据库nas表读取。<br />
	sed -i 's/\#readclients/readclients/g' /etc/raddb/sql.conf<br />
	( you can comment clients.conf inclusion in radiusd.conf<br />
3.d  开在线人数查询支持<br />
	# 查找simul_count_query将279-282行注释去掉<br />
	vim /etc/raddb/sql/mysql/dialup.conf<br />
3.e  修改sites-enabled目录配置文件<br />
	vim /usr/local/etc/raddb/sites-enabled/default<br />
	找到authorize {}模块，注释掉files（159行），去掉sql前的#号（166行）<br />
	找到accounting {}模块，注释掉radutmp(385行),注释掉去掉sql前面的#号(395行)。<br />
	找到session {}模块，注释掉radutmp（439行），去掉sql前面的#号（443行）。<br />
	找到post-auth {}模块，去掉sql前的#号（464行），去掉sql前的#号（552行）。</p>
<p>4. radiusclient configuration<br />
4a. get radiusclient configuration from ppp source package<br />
		mkdir -p /usr/local/etc/radiusclient<br />
	From ppp source code :<br />
		wget ftp://ftp.samba.org/pub/ppp/ppp-2.4.5.tar.gz<br />
		tar zxvf ppp-2.4.5.tar.gz<br />
		cp -R /root/ppp-2.4.5/pppd/plugins/radius/etc/ /usr/local/etc/radiusclient<br />
	From ppp src.rpm<br />
		Amazon: get ppp sro package by : get_reference_code command<br />
		Redhat/Center OS: yumdownloader download the src.rpm<br />
		Debian apt-get source<br />
		rpm2cpio xxx.rpm | cpio -div<br />
		cp -R /root/ppp-2.4.5/pppd/plugins/radius/etc/ /usr/local/etc/radiusclient<br />
4b. 编辑/usr/local/etc/radiusclient/servers，加上一组服务器和密钥，本例中为“MyVPN”：<br />
	localhost MyVPN</p>
<p>4c. Confirm the key is the same in /etc/raddb/clients.conf or nas table in sql<br />
4d. 编辑/usr/local/etc/radiusclient/dictionary，将最后一行改为：<br />
	INCLUDE /usr/local/etc/radiusclient/dictionary.microsoft<br />
	可以再添加一行：<br />
	INCLUDE /usr/local/etc/radiusclient/dictionary.merit<br />
	# add your attribute<br />
	ATTRIBUTE Max-Monthly-Traffic 3003 integer<br />
	ATTRIBUTE Monthly-Traffic-Limit 3004 integer<br />
	ATTRIBUTE Monthly-Traffic 3005 integer</p>
<p>5. PPTP启用freeradius插件<br />
5a. /etc/ppp/options.pptpd, add the folowing<br />
	plugin radius.so<br />
	plugin radattr.so<br />
	radius-config-file /usr/local/etc/radiusclient/radiusclient.conf<br />
5b. if needed<br />
	sed -i 's/logwtmp/\#logwtmp/g' /etc/pptpd.conf<br />
	sed -i 's/radius_deadtime/\#radius_deadtime/g' /usr/local/etc/radiusclient/radiusclient.conf<br />
	sed -i 's/bindaddr/\#bindaddr/g' /usr/local/etc/radiusclient/radiusclient.conf<br />
5c. /etc/ppp/options.xl2tpd, add the following<br />
	plugin radius.so<br />
	plugin radattr.so<br />
	radius-config-file /usr/local/etc/radiusclient/radiusclient.conf</p>
<p>6. 用户权限管理<br />
	# 连接 MySQL 数据库<br />
	mysql -uroot -p123456;</p>
<p>	# 使用 radius 数据库<br />
	USE radius;</p>
<p>	# 添加用户demo，密码demo，注意是在radchec表<br />
	INSERT INTO radcheck (username,attribute,op,VALUE) VALUES ('demo','Cleartext-Password',':=','demo');</p>
<p>	# 将用户demo加入VIP1用户组<br />
	INSERT INTO radusergroup (username,groupname) VALUES ('demo','VIP1');</p>
<p>	# 限制同时登陆人数，注意是在radgroupcheck表<br />
	INSERT INTO radgroupcheck (groupname,attribute,op,VALUE) VALUES ('normal','Simultaneous-Use',':=','1');</p>
<p>	# 其他<br />
	INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('VIP1','Auth-Type',':=','Local');<br />
	INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('VIP1','Service-Type',':=','Framed-User');<br />
	INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('VIP1','Framed-Protocol',':=','PPP');<br />
	INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('VIP1','Framed-MTU',':=','1500');<br />
	INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('VIP1','Framed-Co</p>
<p>7. /etc/init.d/radiusd start</p>
<p>8. freeradius-dialupadmin ( http://wiki.freeradius.org/Dialup-admin )<br />
8.a Add your defined attribute in the /etc/freeradius-dialupadmin<br />
	 checkItem     Max-Monthly-Traffic             Max-Monthly-Traffic<br />
8.b /etc/freeradius-dialupadmin/admin.conf<br />
	mysql database config &#038; test client info<br />
	# table mapping e.g.<br />
	sql_usergroup_table: radusergroup<br />
	#counter default<br />
	counter_default_daily: none<br />
	counter_default_weekly: none<br />
	counter_default_monthly: none<br />
	counter_default_monthly_traffic: none<br />
8.c /usr/share/freeradius-dialupadmin/bin scrtips perl tempfile fix<br />
	#use File::Temp;<br />
	use File::Temp qw/ tempfile /;</p>
<p>9. Others<br />
9a. /etc/raddb/sql.conf<br />
	radius mysql database information, serve, db, user and password etc.<br />
9b. /etc/raddb/dictionary  (add your own attribute is needed )<br />
	ATTRIBUTE Max-Monthly-Traffic 3003 integer<br />
	ATTRIBUTE Monthly-Traffic-Limit 3004 integer<br />
	ATTRIBUTE Monthly-Traffic 3005 integer<br />
9c. /etc/radiusd.conf, initialize your attribue in instantiate section<br />
	#       daily<br />
	dailycounter<br />
	monthlycounter<br />
	monthlytrafficcounter<br />
9d. /etc/raddb/sites-enabled/default<br />
	# in authorize:<br />
	# check dead users after sql<br />
        sql</p>
<p>        if(User-Name) {<br />
        if("%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause='Clear-Stale Session' WHERE UserName='%{User-Name}' and AcctStopTime is null and (TIME_TO_SEC(TIMEDIFF(NOW(),AcctStartTime))-1000)>AcctSessionTime}”){<br />
	 }<br />
	}</p>
<p>	#  Enforce daily limits on time spent logged in.<br />
	#       daily<br />
        monthlytrafficcounter<br />
        dailycounter<br />
        monthlycounter</p>
<p>	# in session<br />
        #  See “Simultaneous Use Checking Queries” in sql.conf<br />
	#       radutmp<br />
        sql<br />
9e. /etc/raddb/sql/mysql/counter.conf</p>
<p>	#  DEFAULT  Max-Daily-Session > 3600, Auth-Type = Reject<br />
	#      Reply-Message = “You&#8217;ve used up more than one hour today”<br />
	#<br />
	sqlcounter dailycounter {<br />
		counter-name = Daily-Session-Time<br />
		check-name = Max-Daily-Session<br />
		reply-name = Session-Timeout<br />
		sqlmod-inst = sql<br />
		key = User-Name<br />
		reset = daily</p>
<p>		# This query properly handles calls that span from the<br />
		# previous reset period into the current period but<br />
		# involves more work for the SQL server than those<br />
		# below<br />
		query = “SELECT SUM(acctsessiontime &#8211; \<br />
			 GREATEST((%b &#8211; UNIX_TIMESTAMP(acctstarttime)), 0)) \<br />
			 FROM radacct WHERE username = &#8216;%{%k}&#8217; AND \<br />
			 UNIX_TIMESTAMP(acctstarttime) + acctsessiontime > &#8216;%b&#8217;”</p>
<p>		# This query ignores calls that started in a previous<br />
		# reset period and continue into into this one. But it<br />
		# is a little easier on the SQL server<br />
	#       query = “SELECT SUM(acctsessiontime) FROM radacct WHERE \<br />
	#                username = &#8216;%{%k}&#8217; AND acctstarttime > FROM_UNIXTIME(&#8216;%b&#8217;)”</p>
<p>		# This query is the same as above, but demonstrates an<br />
		# additional counter parameter &#8216;%e&#8217; which is the<br />
		# timestamp for the end of the period<br />
	#       query = “SELECT SUM(acctsessiontime) FROM radacct \<br />
	#                WHERE username = &#8216;%{%k}&#8217; AND acctstarttime BETWEEN \<br />
	#                FROM_UNIXTIME(&#8216;%b&#8217;) AND FROM_UNIXTIME(&#8216;%e&#8217;)”<br />
	}</p>
<p>	sqlcounter monthlycounter {<br />
		counter-name = Monthly-Session-Time<br />
			check-name = Max-Monthly-Session<br />
			reply-name = Session-Timeout<br />
			sqlmod-inst = sql<br />
			key = User-Name<br />
			reset = monthly</p>
<p>		# This query properly handles calls that span from the<br />
		# previous reset period into the current period but<br />
		# involves more work for the SQL server than those<br />
		# below<br />
		query = “SELECT SUM(acctsessiontime &#8211; \<br />
			 GREATEST((%b &#8211; UNIX_TIMESTAMP(acctstarttime)), 0)) \<br />
			 FROM radacct WHERE username=&#8217;%{%k}&#8217; AND \<br />
			 UNIX_TIMESTAMP(acctstarttime) + acctsessiontime > &#8216;%b&#8217;”</p>
<p>		# This query ignores calls that started in a previous<br />
		# reset period and continue into into this one. But it<br />
		# is a little easier on the SQL server<br />
	#       query = “SELECT SUM(acctsessiontime) FROM radacct WHERE \<br />
	#                username=&#8217;%{%k}&#8217; AND acctstarttime > FROM_UNIXTIME(&#8216;%b&#8217;)”</p>
<p>		# This query is the same as above, but demonstrates an<br />
		# additional counter parameter &#8216;%e&#8217; which is the<br />
		# timestamp for the end of the period<br />
	#       query = “SELECT SUM(acctsessiontime) FROM radacct \<br />
	#                WHERE username=&#8217;%{%k}&#8217; AND acctstarttime BETWEEN \<br />
	#                FROM_UNIXTIME(&#8216;%b&#8217;) AND FROM_UNIXTIME(&#8216;%e&#8217;)”<br />
	}</p>
<p>	sqlcounter monthlytrafficcounter {<br />
	    counter-name = Monthly-Traffic<br />
		check-name = Max-Monthly-Traffic<br />
		reply-name = Monthly-Traffic-Limit<br />
		sqlmod-inst = sql<br />
		key = User-Name<br />
		reset = monthly<br />
	    query = “SELECT SUM(acctinputoctets + acctoutputoctets)/1024 FROM radacct WHERE UserName=&#8217;%{%k}&#8217; AND UNIX_TIMESTAMP(AcctStartTime) + acctsessiontime > &#8216;%b&#8217;”<br />
	}<br />
9f.  radius databaase<br />
	# nas<br />
	insert your radius client<br />
	# radcheck<br />
	Cleartext-Password := password<br />
	# radgroupcheck<br />
	Simultaneous-Use := 2<br />
	Max-Daily-Session := 21600<br />
	Max-Monthly-Session := 345600<br />
	Max-Monthly-Traffic := 5242880		(5GB, KB Unit)<br />
	#radgroupreply<br />
	VIP	Acct-Interim-Interval := 300<br />
	VIP	Idle-Timeout := 600<br />
	#radusergroup<br />
	username groupname</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/750/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PPTP VPN安装配置 &#8211; Amazon EC2</title>
		<link>http://www.fallday.org/archives/745</link>
		<comments>http://www.fallday.org/archives/745#comments</comments>
		<pubDate>Fri, 13 Jan 2012 17:55:24 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[PPTP]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=745</guid>
		<description><![CDATA[Amazon EC2安装配置第二篇，PPTP VPN 1. 安装pptpd #wget http://poptop.sourceforge.net/yum/stable/rhel6/i386/pptpd-1.3.4-2.el6.i686.rpm #yum localinstall pptpd-1.3.4-2.el6.i686.rpm 2. 配置pptpd #vi /etc/pptpd.conf localip 192.168.9.1 remoteip 192.168.9.11-30 3. 编辑options.pptpd #vi /etc/ppp/options.pptpd ms-dns 208.67.222.222 ms-dns 208.67.220.220 # plugin for radius # plugin radius.so # plugin radattr.so # radius-config-file /usr/local/etc/radiusclient/radiusclient.conf 4. 设置PPTP用户密码 #vi /etc/ppp/chap-secrets myusername pptpd mypassword * 5. 设置ip转发状态为生效，然后立即载入（NAT转发） #vi /etc/sysctl.conf net.ipv4.ip_forward = 1 #/sbin/sysctl [...]]]></description>
			<content:encoded><![CDATA[<p>Amazon EC2安装配置第二篇，PPTP VPN</p>
<p>1. 安装pptpd<br />
#wget http://poptop.sourceforge.net/yum/stable/rhel6/i386/pptpd-1.3.4-2.el6.i686.rpm<br />
#yum localinstall pptpd-1.3.4-2.el6.i686.rpm</p>
<p>2. 配置pptpd<br />
#vi /etc/pptpd.conf</p>
<pre>
localip 192.168.9.1
remoteip 192.168.9.11-30
</pre>
<p><span id="more-745"></span>3. 编辑options.pptpd<br />
#vi /etc/ppp/options.pptpd</p>
<pre>
ms-dns 208.67.222.222
ms-dns 208.67.220.220

# plugin for radius
# plugin radius.so
# plugin radattr.so
# radius-config-file /usr/local/etc/radiusclient/radiusclient.conf
</pre>
<p>4. 设置PPTP用户密码<br />
#vi /etc/ppp/chap-secrets</p>
<pre>
myusername pptpd mypassword *
</pre>
<p>5.  设置ip转发状态为生效，然后立即载入（NAT转发）<br />
#vi /etc/sysctl.conf</p>
<pre>
net.ipv4.ip_forward = 1
</pre>
<p>#/sbin/sysctl -p</p>
<p>6. 启动iptables规则，设置NAT转发，然后保存（iptables本身就是开机启动的）<br />
#/sbin/service iptables start<br />
#iptables &#8211;table nat &#8211;append POSTROUTING &#8211;jump MASQUERADE<br />
#service iptables save</p>
<p>7 启动pptpd服务，并且设置为开机启动<br />
#/sbin/service pptpd start<br />
#chkconfig pptpd on</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/745/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>L2TP/IPSec VPN安装配置 &#8211; Amazon EC2</title>
		<link>http://www.fallday.org/archives/741</link>
		<comments>http://www.fallday.org/archives/741#comments</comments>
		<pubDate>Fri, 13 Jan 2012 17:32:22 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[L2TP/IPSec]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=741</guid>
		<description><![CDATA[博客移到了Amazon EC2, 记录一些服务的安装配置。第一篇L2TP/IPSec VPN安装配置。 1. 安装配置openswan #yum install openswan 2. 编辑 ipsec.conf #vi /etc/ipsec.conf # /etc/ipsec.conf - Openswan IPsec configuration file # # Manual: ipsec.conf.5 # # Please place your own config files in /etc/ipsec.d/ ending in .conf version 2.0 # conforms to second version of ipsec.conf specification # basic configuration config setup # Debug-logging [...]]]></description>
			<content:encoded><![CDATA[<p>博客移到了Amazon EC2, 记录一些服务的安装配置。第一篇L2TP/IPSec VPN安装配置。</p>
<p>1. 安装配置openswan<br />
#yum install openswan</p>
<p>2. 编辑 ipsec.conf<br />
#vi /etc/ipsec.conf<br />
<span id="more-741"></span>
<pre>
# /etc/ipsec.conf - Openswan IPsec configuration file
#
# Manual:     ipsec.conf.5
#
# Please place your own config files in /etc/ipsec.d/ ending in .conf

version 2.0     # conforms to second version of ipsec.conf specification

# basic configuration
config setup
        # Debug-logging controls:  "none" for (almost) none, "all" for lots.
        # klipsdebug=none
        # plutodebug="control parsing"
        # klipsdebug=all
        # plutodebug="control parsing"
        # For Red Hat Enterprise Linux and Fedora, leave protostack=netkey
        protostack=netkey
        nat_traversal=yes
        virtual_private=
        oe=off
        # Enable this if you see "failed to find any available worker"
        nhelpers=0

#You may put your configuration (.conf) file in the "/etc/ipsec.d/"
#include /etc/ipsec.d/*.conf

conn L2TP-PSK-NAT
  rightsubnet=vhost:%priv
  also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
  authby=secret
  pfs=no
  auto=add
  keyingtries=3
  rekey=no
  ikelifetime=8h
  keylife=1h
  type=transport
  left=xxx.xxx.xxx.xxx
  leftprotoport=17/1701
  right=%any
  rightprotoport=17/%any
  #enable DPD
  dpddelay=40
  dpdtimeout=130
  dpdaction=clear
</pre>
<p>(上面的IP配置, AWS EC2需使用实例对应的内网IP)</p>
<p>3. 设置IPSec密钥<br />
#vi /etc/ipsec.secrets</p>
<pre>
# include /etc/ipsec.d/*.secrets
xxx.xxx.xxx.xxx   %any:  PSK "vpnsecret"
</pre>
<p>(上面的IP配置, AWS EC2需使用Instance对应的内网IP)</p>
<p>4. 修改包转发设置, 在终端窗口运行</p>
<pre>
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
</pre>
<p>5. 重启 IPSec ，测试<br />
#/etc/init.d/ipsec restart<br />
#ipsec verify</p>
<p>6. 安装L2TP<br />
#yum &#8211;enablerepo=epel install xl2tpd</p>
<p>7. 编辑 xl2tpd.conf<br />
#vi /etc/xl2tpd/xl2tpd.conf</p>
<pre>
[global]
; listen-addr = 192.168.1.98
;
; requires openswan-2.5.18 or higher - Also does not yet work in combination
; with kernel mode l2tp as present in linux 2.6.23+
; ipsec saref = yes
; forceuserspace = yes
;
; debug tunnel = yes

[lns default]
ip range = 192.168.11.128-192.168.11.254
local ip = 192.168.11.99
;require chap = yes
refuse chap = yes
refuse pap = yes
require authentication = yes
;name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
</pre>
<p>8. 配置ppp<br />
#vi /etc/ppp/options.xl2tpd</p>
<pre>
name l2tpd
ipcp-accept-local
ipcp-accept-remote
ms-dns  8.8.8.8
ms-dns  8.8.4.4
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
# nodefaultroute
debug
lock
proxyarp
connect-delay 5000

# plugin for radius
# plugin radius.so
# plugin radattr.so
# radius-config-file /usr/local/etc/radiusclient/radiusclient.conf
</pre>
<p>9. 设置VPN用户密码<br />
#vi /etc/ppp/chap-secrets</p>
<pre>
# user      server      password            ip
username        l2tpd       userpass        *
</pre>
<p>10. 启用包转发<br />
#iptables &#8211;table nat &#8211;append POSTROUTING &#8211;jump MASQUERADE<br />
#echo 1 > /proc/sys/net/ipv4/ip_forward</p>
<p>11. 修改 sysctl.conf<br />
#vi /etc/sysctl.conf</p>
<pre>
net.netfilter.nf_conntrack_acct=1
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
</pre>
<p>12. 配置开机启动<br />
#chkconfig ipsec on<br />
#chkconfig xl2tpd on<br />
#/etc/init.d/iptables save</p>
<p>13. 编辑rc.local<br />
#vi /etc/rc.local</p>
<pre>
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
</pre>
<p>14. 启动服务<br />
#/etc/init.d/iptables restart<br />
#/etc/init.d/ipsec restart<br />
#/etc/init.d/xl2tpd restart</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/741/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HostGator空间和WHMCS试用</title>
		<link>http://www.fallday.org/archives/727</link>
		<comments>http://www.fallday.org/archives/727#comments</comments>
		<pubDate>Thu, 29 Dec 2011 13:24:53 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[HostGator]]></category>
		<category><![CDATA[WHMCS]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=727</guid>
		<description><![CDATA[看到一些评论说Hostgator的空间服务还是不错的，Reseller的Plan还可以有免费的WHMCS赠送。前几天HostGator因反对SOPA提案放出nosopa的五折优惠码(12.31前有效)，一时禁不信诱惑就买了一个。主要是想试用一下WHMCS。 购买很顺利，网上有人说国人购买需要提交身份证件之类的，自己还有些担心。下了单后就收到开通邮件了，之后两三钟电话响了，原来是Hostgator的的确认电话。电话很不清楚，可能是用的IP电话，不过问题很简单，姓什么? 是自己付的款吗? 之后就帐号已经激活。 趁着周末和公司补的圣诞节假期，好整个Hostgator及WHMCS试一下，不但加入了Hostgator的空间产品，也把自己手里的一个Linode VPS也加了进去，基于Virtualmin面板提供空间服务。另外也做了一个VPN的自动销售开通的WHMCS模块。以后有空的时间可以细说一下过程。总之WHMCS还真的是很赞的。]]></description>
			<content:encoded><![CDATA[<p>看到一些评论说Hostgator的空间服务还是不错的，Reseller的Plan还可以有免费的WHMCS赠送。前几天HostGator因反对SOPA提案放出nosopa的五折优惠码(12.31前有效)，一时禁不信诱惑就买了一个。主要是想试用一下WHMCS。</p>
<p>购买很顺利，网上有人说国人购买需要提交身份证件之类的，自己还有些担心。下了单后就收到开通邮件了，之后两三钟电话响了，原来是Hostgator的的确认电话。电话很不清楚，可能是用的IP电话，不过问题很简单，姓什么? 是自己付的款吗? 之后就帐号已经激活。</p>
<p><span id="more-727"></span>趁着周末和公司补的圣诞节假期，好整个Hostgator及WHMCS试一下，不但加入了Hostgator的空间产品，也把自己手里的一个Linode VPS也加了进去，基于Virtualmin面板提供空间服务。另外也做了一个VPN的自动销售开通的WHMCS模块。以后有空的时间可以细说一下过程。总之WHMCS还真的是很赞的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/727/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Acct-Interim-Interval : 控制FreeRadius的用量测量更新周期</title>
		<link>http://www.fallday.org/archives/723</link>
		<comments>http://www.fallday.org/archives/723#comments</comments>
		<pubDate>Tue, 29 Nov 2011 17:28:06 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[FreeRadius]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=723</guid>
		<description><![CDATA[默认安装配置下，NAS只是在连接开始及结束时发送帐户用量测量信息，如果连接异常中断时，NAS有时并不会发送结束及测量结束。如果用户长时间连接又异常中断，测量结果便会有较大出入。 FreeRadius可以通过设置Acct-Interim-Interval响应参数来要求NAS Acct更新周期。可以在radgroupreplay或者radreply中对组或者用户进户设置。比如设置帐户更新周期为300秒。 Acct-Interim-Interval  = 300 当然，这也取决于NAS是否支持Acct-Interim-Interval 设置。]]></description>
			<content:encoded><![CDATA[<p>默认安装配置下，NAS只是在连接开始及结束时发送帐户用量测量信息，如果连接异常中断时，NAS有时并不会发送结束及测量结束。如果用户长时间连接又异常中断，测量结果便会有较大出入。</p>
<p>FreeRadius可以通过设置Acct-Interim-Interval响应参数来要求NAS Acct更新周期。可以在radgroupreplay或者radreply中对组或者用户进户设置。比如设置帐户更新周期为300秒。</p>
<p>Acct-Interim-Interval  = 300</p>
<p>当然，这也取决于NAS是否支持Acct-Interim-Interval 设置。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/723/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeRadius异常在线用户的清除</title>
		<link>http://www.fallday.org/archives/721</link>
		<comments>http://www.fallday.org/archives/721#comments</comments>
		<pubDate>Tue, 29 Nov 2011 16:31:01 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[FreeRadius]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=721</guid>
		<description><![CDATA[FreeRaidus在一些情况，用户的连接已经断开，但系统中用户还处于在线状态。如果用户再次从同一IP再次登录或者服务限制一个用户不能同时多处登录时就会连接认证失败。其次FreeRaidus真是一个不错的系统，可以自己写一段SQL来处理这个情况。SQL放在/etc/freeradius/sites-enable/default的authorize section即可。 if(User-Name) { if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; and CallingStationId=&#8217;%{Calling-Station-Id}&#8217; and AcctStopTime is null}”){ } } 如果不允许一个用户同时多处登录，去掉Calling-Station-Id的条件即可。 if(User-Name) { if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; and AcctStopTime is null}”){ } } 注意这里sql是有意放在一个空的if语句中，因为在freeradius的配置文件中，一般语句中的sql会要求有返回值。放在if条件中可以避免因为检查返回值失败。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; 补记： 再想想这样做也还有些问题，因为只是在数据库中清除了状态，如果前一个连接物理上还存在的话，并不能物理上断开相应的连接。完美解决方案需要NAS能检查连接状态，如果NAS不提供相应功能的话，不能有完好解决方案。 折中的方案是通过Acct-Interim-Interval设置NAS更新数据周期，在检查无效连接时只处理一段时间(比如三个更新周期)没有更新数据的连接。一点问题是如果一个连接异常断开后，在一段时间内无法再次登陆。 if(User-Name) { if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p>FreeRaidus在一些情况，用户的连接已经断开，但系统中用户还处于在线状态。如果用户再次从同一IP再次登录或者服务限制一个用户不能同时多处登录时就会连接认证失败。其次FreeRaidus真是一个不错的系统，可以自己写一段SQL来处理这个情况。SQL放在/etc/freeradius/sites-enable/default的authorize section即可。</p>
<p>if(User-Name) {<br />
if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; and CallingStationId=&#8217;%{Calling-Station-Id}&#8217; and AcctStopTime is null}”){<br />
}<br />
}</p>
<p><span id="more-721"></span>如果不允许一个用户同时多处登录，去掉Calling-Station-Id的条件即可。</p>
<p>if(User-Name) {<br />
if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; and AcctStopTime is null}”){<br />
}<br />
}</p>
<p>注意这里sql是有意放在一个空的if语句中，因为在freeradius的配置文件中，一般语句中的sql会要求有返回值。放在if条件中可以避免因为检查返回值失败。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>补记：</p>
<p>再想想这样做也还有些问题，因为只是在数据库中清除了状态，如果前一个连接物理上还存在的话，并不能物理上断开相应的连接。完美解决方案需要NAS能检查连接状态，如果NAS不提供相应功能的话，不能有完好解决方案。</p>
<p>折中的方案是通过Acct-Interim-Interval设置NAS更新数据周期，在检查无效连接时只处理一段时间(比如三个更新周期)没有更新数据的连接。一点问题是如果一个连接异常断开后，在一段时间内无法再次登陆。</p>
<p>if(User-Name) {<br />
if(“%{sql:UPDATE radacct set AcctStopTime=ADDDATE(AcctStartTime,INTERVAL AcctSessionTime SECOND),AcctTerminateCause=&#8217;Clear-Stale Session&#8217; WHERE UserName=&#8217;%{User-Name}&#8217; and AcctStopTime is null and (TIME_TO_SEC(TIMEDIFF(NOW(),AcctStartTime))-1000)&gt;AcctSessionTime}”){<br />
}<br />
}</p>
<p>//示例是1000秒没有新数据即清除状态</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/721/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP FastCGI做Apache虚拟主机用户隔离</title>
		<link>http://www.fallday.org/archives/714</link>
		<comments>http://www.fallday.org/archives/714#comments</comments>
		<pubDate>Sun, 27 Nov 2011 09:00:41 +0000</pubDate>
		<dc:creator>fallday</dc:creator>
				<category><![CDATA[主机管理]]></category>
		<category><![CDATA[云计算]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SuExec]]></category>

		<guid isPermaLink="false">http://www.fallday.org/?p=714</guid>
		<description><![CDATA[共享主机的情况，设置每个虚拟主机的进程在单独的用户下会相对安全。在PHP的情况下，可以通过PHP FastCGI及SuExec来实现。 1. CentOS可以从EPEL中安装mod_fcgid yum install httpd php-cli mod_fcgid 2. vi /etc/php.ini cgi.fix_pathinfo = 1 3. 创建vhosts First we create the users and groups: groupadd web1 groupadd web2 useradd -s /bin/false -d /var/www/web1 -m -g web1 web1 useradd -s /bin/false -d /var/www/web2 -m -g web2 web2 chmod 755 /var/www/web1 chmod 755 /var/www/web2 Then we create [...]]]></description>
			<content:encoded><![CDATA[<p>共享主机的情况，设置每个虚拟主机的进程在单独的用户下会相对安全。在PHP的情况下，可以通过PHP FastCGI及SuExec来实现。</p>
<p>1. CentOS可以从EPEL中安装mod_fcgid</p>
<p>yum install httpd php-cli mod_fcgid</p>
<p>2. vi /etc/php.ini</p>
<p>cgi.fix_pathinfo = 1</p>
<p>3. 创建vhosts</p>
<p><span id="more-714"></span>First we create the users and groups:</p>
<p>groupadd web1<br />
groupadd web2<br />
useradd -s /bin/false -d /var/www/web1 -m -g web1 web1<br />
useradd -s /bin/false -d /var/www/web2 -m -g web2 web2<br />
chmod 755 /var/www/web1<br />
chmod 755 /var/www/web2</p>
<p>Then we create the document roots and make them owned by the users/groups web1 resp. web2:</p>
<p>mkdir -p /var/www/web1/web<br />
chown web1:web1 /var/www/web1/web<br />
mkdir -p /var/www/web2/web<br />
chown web2:web2 /var/www/web2/web</p>
<p>We will run PHP using suExec; suExec’s document root is /var/www, as the following command shows:</p>
<p>/usr/sbin/suexec -V</p>
<p>[root@server1 ~]# /usr/sbin/suexec -V<br />
-D AP_DOC_ROOT=”/var/www”<br />
-D AP_GID_MIN=100<br />
-D AP_HTTPD_USER=”apache”<br />
-D AP_LOG_EXEC=”/var/log/httpd/suexec.log”<br />
-D AP_SAFE_PATH=”/usr/local/bin:/usr/bin:/bin”<br />
-D AP_UID_MIN=500<br />
-D AP_USERDIR_SUFFIX=”public_html”<br />
[root@server1 ~]#</p>
<p>Therefore we cannot call the PHP binary (/usr/bin/php-cgi) directly because it is located outside suExec’s document root. As suExec does not allow symlinks, the only way to solve the problem is to create a wrapper script for each web site in a subdirectory of /var/www; the wrapper script will then call the PHP binary /usr/bin/php-cgi. The wrapper script must be owned by the user and group of each web site, therefore we need one wrapper script for each web site. I’m going to create the wrapper scripts in subdirectories of /var/www/php-fcgi-scripts, e.g. /var/www/php-fcgi-scripts/web1 and /var/www/php-fcgi-scripts/web2.</p>
<p>mkdir -p /var/www/php-fcgi-scripts/web1<br />
mkdir -p /var/www/php-fcgi-scripts/web2</p>
<p>vi /var/www/php-fcgi-scripts/web1/php-fcgi-starter</p>
<table width="90%" border="1" cellspacing="0" cellpadding="2" align="center" bgcolor="#cccccc">
<tbody>
<tr>
<td>
<pre>#!/bin/sh
PHPRC=/etc/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi</pre>
</td>
</tr>
</tbody>
</table>
<p>vi /var/www/php-fcgi-scripts/web2/php-fcgi-starter</p>
<table width="90%" border="1" cellspacing="0" cellpadding="2" align="center" bgcolor="#cccccc">
<tbody>
<tr>
<td>
<pre>#!/bin/sh
PHPRC=/etc/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi</pre>
</td>
</tr>
</tbody>
</table>
<p>The PHPRC line contains the directory where the php.ini file is located (i.e., /etc/ translates to /etc/php.ini). PHP_FCGI_MAX_REQUESTS is the maximum number of requests before an fcgid process is stopped and a new one is launched. PHP_FCGI_CHILDREN defines the number of PHP children that will be launched.</p>
<p>The php-fcgi-starter scripts must be executable, and they (and the directories they are in) must be owned by the web site’s user and group:</p>
<p>chmod 755 /var/www/php-fcgi-scripts/web1/php-fcgi-starter<br />
chmod 755 /var/www/php-fcgi-scripts/web2/php-fcgi-starter<br />
chown -R web1:web1 /var/www/php-fcgi-scripts/web1<br />
chown -R web2:web2 /var/www/php-fcgi-scripts/web2</p>
<p>Now we create the Apache vhosts for www.example1.com and www.example2.com. Add the following two vhosts at the end of /etc/httpd/conf/httpd.conf:</p>
<p>vi /etc/httpd/conf/httpd.conf</p>
<table width="90%" border="1" cellspacing="0" cellpadding="2" align="center" bgcolor="#cccccc">
<tbody>
<tr>
<td>
<pre>[...]
NameVirtualHost *:80

&lt;VirtualHost *:80&gt;
  ServerName www.example1.com
  ServerAlias example1.com
  ServerAdmin webmaster@example1.com
  DocumentRoot /var/www/web1/web/

  &lt;IfModule mod_fcgid.c&gt;
    SuexecUserGroup web1 web1
    PHP_Fix_Pathinfo_Enable 1
    &lt;Directory /var/www/web1/web/&gt;
      Options +ExecCGI
      AllowOverride All
      AddHandler fcgid-script .php
      FCGIWrapper /var/www/php-fcgi-scripts/web1/php-fcgi-starter .php
      Order allow,deny
      Allow from all
    &lt;/Directory&gt;
  &lt;/IfModule&gt;

  # ErrorLog /var/log/apache2/error.log
  # CustomLog /var/log/apache2/access.log combined
  ServerSignature Off

&lt;/VirtualHost&gt;

&lt;VirtualHost *:80&gt;
  ServerName www.example2.com
  ServerAlias example2.com
  ServerAdmin webmaster@example2.com
  DocumentRoot /var/www/web2/web/

  &lt;IfModule mod_fcgid.c&gt;
    SuexecUserGroup web2 web2
    PHP_Fix_Pathinfo_Enable 1
    &lt;Directory /var/www/web2/web/&gt;
      Options +ExecCGI
      AllowOverride All
      AddHandler fcgid-script .php
      FCGIWrapper /var/www/php-fcgi-scripts/web2/php-fcgi-starter .php
      Order allow,deny
      Allow from all
    &lt;/Directory&gt;
  &lt;/IfModule&gt;

  # ErrorLog /var/log/apache2/error.log
  # CustomLog /var/log/apache2/access.log combined
  ServerSignature Off

&lt;/VirtualHost&gt;</pre>
</td>
</tr>
</tbody>
</table>
<p>Make sure you fill in the right paths (and the correct user and group in the SuexecUserGroup lines).</p>
<p>Reload Apache afterwards:</p>
<p>/etc/init.d/httpd reload</p>
<p>原文链接：http://www.mounix.com/blog/2011/08/how-to-set-up-apache2-with-mod_fcgid-and-php5-on-centos-5-6/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fallday.org/archives/714/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

