SSH authorized_keys permission
~/.ssh/authorized_keys content:
ssh-rsa <KEY> username@computername
Set correct permission to enable public key SSH login
chmod 400 ~/.ssh/authorized_keys chmod 700 ~/.ssh
~/.ssh/authorized_keys content:
ssh-rsa <KEY> username@computername
Set correct permission to enable public key SSH login
chmod 400 ~/.ssh/authorized_keys chmod 700 ~/.ssh
I’m a noob in using Git, and I’m using Github to host some of the code I wrote. Here are some basic commands to host a project with Github (or using Git revision control generally) (sometimes I forgot the command or the order of which command goes first)
Global setup:
Set up git
git config --global user.name "Your Name" git config --global user.email myemail@maildomain.com
Next steps:
mkdir project-name cd project-name git init touch README git add README git commit -m 'first commit' git remote add origin git@github.com:username/project-name.git git push -u origin master
Existing Git Repo?
cd existing_git_repo git remote add origin git@github.com:username/project-name.git git push -u origin master
To commit changes (and optionally push changes to Github)
git add . git commit -m 'commit message' git push -u origin master
Common SVN users may find it confusing when using Git. Here’s some of the tips:
Session handling in phpBB3 requires a user to use one IP address per session, therefore if your IP address changed, you will be prompt to login again.
Cloudflare is a web caching service that cache static contents of a website by acting as the nameserver that manage the website domain name. Therefore, every request to the domain name will pass through Cloudflare system first and any cached contents will be served from Cloudflare servers instead of the web hosting server.
However, when using Cloudflare service, the REMOTE_ADDR value for PHP $_SERVER will follow Cloudflare servers IP address. Therefore, you might face problem when using phpBB (or any other web app that rely on session tied to the IP address) with this service.
So, we need to edit phpBB session.php file to grab the correct variable for the users’ real IP address. Edit includes/session.php
Find:
$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '';
Replace with:
$this->ip = (!empty($_SERVER['HTTP_CF_CONNECTING_IP']))
? (string) $_SERVER['HTTP_CF_CONNECTING_IP']
: ((!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '');
HTTP_CF_CONNECTING_IP is special header value passed by Cloudflare servers containing visitors’ real IP address, and in case this variable not set, we use the good ol REMOTE_ADDR
In case someone stumbled upon this problem:
1. You download and install the new release of phpBB (3.0.9) and immediately integrate SEO Ultimate URL package
2. The setup went well except you found out that the page is looked ugly because the CSS wasn’t loaded – cause by the URL got backslash in it:
http://localhost/\/style.php …
To fix, you need to edit the data in the config table:
1. Access the phpBB3 config table (phpbb_config)
2. Lookup for config_name = ‘script_path’
3. You’ll see the value is ‘\/’. Change this to ‘/’
4. Save the data
Clear the cache, and reload the page. You should see the pretty page back again!
Additional: I’m using localhost with custom port number (82) as testing platform. So in case you’re not getting the image out on the page (caused by the URL generated become http://localhost/style… instead of http://localhost:82/style…, so you need to edit the force server URL settings
1. Go to admin control panel, General > Server Settings
2. Set ‘Force Server URL’ to ‘Yes’
WordPress data validation has some good reference in doing data validation, especially the philosophy part. For best practice, always use format correction first, then use whitelist.
// format correction
$action = (int) $_GET['action'];
// whitelist
switch ($action) {
case 1:
do_this();
break;
case 2:
do_that();
break;
case 0:
default:
die("Don't know this action!");
}
However the above example is only for one input ($_GET['action']). What if your web app (or controller) need a few inputs, and surely you don’t want to write the same code over again, like this
// correct the format
$id = (int) $_GET['id'];
$name = (string) trim($_POST['name']);
$email = (string) trim($_POST['email');
$about = (string) htmlspecialchars(trim($_POST['about']), ENT_QUOTES, 'UTF-8');
// then do validation
if ($id == 0) {
$id = 1;
}
if (empty($name)) {
$msg = 'Name is required';
}
...
Most PHP frameworks I know whether validate the input one by one or using just one input source (GET or POST or COOKIE). It’s better to use $_REQUEST, since some input can be passed in <form> or just query string. E.g. /blog/post/?id=10&do=edit, then inside the page got <input type="hidden" name="do" value="save" />, now you can use both input from $_REQUEST['do'], which determine what action need to be done
$do = (string) $_REQUEST['do'];
switch ($do) {
case 'edit':
get_post($id);
break;
case 'save':
save_post($id);
break;
case 'view':
default:
view_post($id);
break;
}
With that pattern, here comes PHP filter functions, filter_input_array(). It receive an array of arguments, and source type (GET/POST etc.) and validate each of the input. It will return false on failed validation. This function is really convenient when we need to validate a long list of inputs.
However there’s a drawback. Since all the validation can be put in one input key argument (‘input_name’ => array(…list of various validators…), it is difficult to provide accurate error message, of which validation that failed. Therefore we can recreate another filter_input_array(), and put in the previous pattern (format first, then whitelist) into it. So basically the validation function work like this:
$input = validate_input(array(
'id' => array('filter' => 'int', 'options' => array(
'range' => array('max' => 1000, 'msg' => 'Max. value for ID is 1000')
)),
'name' => array('filter' => 'string', 'options' => array(
'required' => array('value' => true, 'msg' => 'This input is required'),
'alphanumeric' => array('value' => true, 'msg' => 'Name need to be alphanumeric')
))
));
// now we can use $input
$input['id'];
$input['name'];
// to get error msg
$err_msg['id']; // which may contain the error msg of specific validator
$err_msg['name'];
// to check if the whole form passed the validator or not, simply:
if (empty($err_msg)) {
// form is valid
}
Additional note: String input.
To sanitize the string input, actually trim() is enough, and can be directly stored in database. You only need to sanitize the value only when outputting it. When echo() the value to HTML, make sure to always encode it first:
<p class="comments"><?php echo htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); ?></p>
This not only can prevent XSS issue, but also display the correct Unicode character. Avoid htmlentities() as it may corrupt the Unicode characters
This setup is using Apache 2.2 bundled with XAMPP, in Windows 7
Create new config file: /xampp/apache/conf/extra/httpd-cache-proxy.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
Listen 3128
NameVirtualHost *:3128
<VirtualHost *:3128>
ErrorLog "logs/proxy-error.log"
CustomLog "logs/proxy-access.log" combined
<IfModule mod_proxy.c>
ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Proxy>
</IfModule>
<IfModule mod_cache.c>
LoadModule disk_cache_module modules/mod_disk_cache.so
<IfModule mod_disk_cache.c>
CacheEnable disk /
CacheRoot "c:/xampp/apache/proxy/cache"
CacheDirLevels 3
CacheDirLength 5
CacheMaxFileSize 10485760
CacheMaxExpire 2592000
</IfModule>
ProxyTimeout 60
</IfModule>
</VirtualHost>
Include this file to /xampp/apache/conf/httpd.conf
Include conf/extra/httpd-cache-proxy.conf
Make sure to create folder for CacheRoot. Restart Apache using XAMPP control panel or Windows Services (if you installed as service), and set browser’s proxy server to 127.0.0.1:3128.
Assuming you have installed Android SDK, (in my case, I don’t have Android Market installed)
adb command. (Make sure Android emulator is running)
android-sdk-windows/platform-tools/adb push file.apk /sdcard/
file:///sdcard/file.apkGet source (get the latest stable version):
cd /tmp wget http://www.squid-cache.org/Versions/v2/2.7/squid-2.7.STABLE9.tar.bz2
Install compiler
yum install gcc
Compile & install squid
./configure --prefix=/opt/squid make all make install
Squid configuration (in /opt/squid/etc folder):
squid.conf
acl all src all acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl localnet src 10.0.0.0/8 # RFC1918 possible internal network acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl Safe_ports port 70 # gopher acl Safe_ports port 210 # wais acl Safe_ports port 1025-65535 # unregistered ports acl Safe_ports port 280 # http-mgmt acl Safe_ports port 488 # gss-http acl Safe_ports port 591 # filemaker acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT http_access allow manager localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localhost http_access allow localnet http_access deny all icp_access allow localnet icp_access deny all http_port 3128 hierarchy_stoplist cgi-bin ? cache_mem 2048 MB maximum_object_size_in_memory 1024 KB cache_dir ufs /var/cache/squid 10000 16 256 maximum_object_size 128 MB access_log /var/log/squid/access.log squid cache_log /var/log/squid/cache.log cache_store_log /var/log/squid/store.log pid_filename /var/run/squid.pid netdb_filename /var/log/squid/netdb.state storeurl_rewrite_children 50 refresh_pattern ^ftp: 1440 20% 10080 ignore-no-cache override-expire ignore-private refresh_pattern ^http://[A-Za-z0-9]+\.lscache[0-9]\.c\.youtube\.com 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern ^http://[a-z0-9]+\.youtube\.com 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern ^http://[a-z]+\.youtube\.com 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern ^http://[a-z0-9]+\.ytimg\.com 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern ^http://*\.youtube\.com 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern get_video\?video_id 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern youtube\.com/get_video\? 9999999 90% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern ^http://*.youtube.com/.* 9999999 100% 999999999 ignore-no-cache override-expire ignore-private refresh_pattern (get_video\?|videoplayback\?|videodownload\?) 10080 99.99999% 999999 override-expire ignore-reload ignore-private negative-ttl=0 refresh_pattern -i ^http:\/\/kh(.*?)\.google\.com(.*?)\/(.*?)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern -i ^http:\/\/mt(.*?)\.google\.com(.*?)\/(.*?)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern -i ^http:\/\/i(.*?)\.wikimapia\.org(.*?)\/(.*?)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern -i \.(gif|png|jpg|jpeg|ico)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern -i \.(iso|avi|wav|mp3|mp4|mpeg|swf|flv|x-flv|mpg|wma|ogg|wmv|asx|asf)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern -i \.(deb|rpm|exe|zip|tar|tgz|ram|rar|bin|ppt|doc|tiff|pdf|jar)$ 999999 90% 9999999 override-expire ignore-reload ignore-no-cache ignore-private refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 40% 4320 acl store_rewrite_list url_regex -i \.youtube\.com\/get_video\? acl store_rewrite_list url_regex -i \.youtube\.com\/videoplayback\.youtube\.com\/videoplay \.youtube\.com\/get_video\? acl store_rewrite_list url_regex -i \.youtube\.[a-z][a-z]\/videoplayback\.youtube\.[a-z][a-z]\/videoplay \.youtube\.[a-z][a-z]\/get_video\? acl store_rewrite_list url_regex -i \.googlevideo\.com\/videoplayback\.googlevideo\.com\/videoplay \.googlevideo\.com\/get_video\? acl store_rewrite_list url_regex -i \.google\.com\/videoplayback\.google\.com\/videoplay \.google\.com\/get_video\? acl store_rewrite_list url_regex -i \.google\.[a-z][a-z]\/videoplayback\.google\.[a-z][a-z]\/videoplay \.google\.[a-z][a-z]\/get_video\? acl store_rewrite_list url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/videoplayback\? acl store_rewrite_list url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/videoplay\? acl store_rewrite_list url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/get_video\? acl store_rewrite_list url_regex -i http://video\..*fbcdn\.net.*\.mp4.* acl store_rewrite_list url_regex -i http://.[0-9]\.[0-9][0-9]\.channel\.facebook\.com/.* acl store_rewrite_list url_regex -i http://.*\.mp4? acl store_rewrite_list url_regex -i http://www\.facebook\.com/ajax/flash/.* acl store_rewrite_list url_regex -i http://.*\.ak\.fbcdn\.net/.* acl store_rewrite_list url_regex -i \.geo.yahoo\.com\? storeurl_access allow store_rewrite_list storeurl_access deny all storeurl_rewrite_program /opt/squid/etc/youtube.pl redirect_program /opt/squid/etc/adzap.pl quick_abort_min 500 KB acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9] upgrade_http0.9 deny shoutcast acl apache rep_header Server ^Apache broken_vary_encoding allow apache cache_mgr admin@datacenter cache_effective_user squid cache_effective_group squid dns_nameservers 208.67.222.222 dns_nameservers 208.67.220.220 visible_hostname datacenter coredump_dir /var/cache/squid
adzap.pl – Get from http://adzapper.sourceforge.net/
wget http://adzapper.sourceforge.net/scripts/squid_redirect mv squid_redirect adzap.pl chmod +x adzap.pl
youtube.pl (this file need to set as executable too – chmox +x youtube.pl)
#!/usr/bin/perl
$|=1;
while (<>) {
@X = split;
$url = $X[0];
if ($url=~s@^http://(.*?)/videoplayback\?(.*)id=(.*?)&.*@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)/videoplayback\?(.*)id=(.*?)@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)/videoplay\?(.*)id=(.*?)&.*@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)/videoplay\?(.*)id=(.*?)@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)/get_video\?(.*)video_id=(.*?)&.*@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)/get_video\?(.*)video_id=(.*?)@squid://videos.youtube.INTERNAL/ID=$3@){}
elsif
($url=~s@^http://(.*?)rapidshare(.*?)/files/(.*?)/(.*?)/(.*?)@squid://files.rapidshare.INTERNAL/$5@){}
elsif
($url=~s@^http://(.*?)fbcdn\.net/(.*?)/(.*?)/(.*?\.jpg)@squid://files.facebook.INTERNAL/$4@){}
elsif
($url=~s@^http://contenidos2(.*?)/(.*?)@squid://files.contenidos2.INTERNAL/$2@){}
elsif
($url=~s@^http://cdn(.*?)/([0-9a-zA-Z_-]*?\.flv)@squid://files.cdn.INTERNAL/$2@){}
elsif
($url=~s@^http://web.vxv.com/data/media/(.*?)@squid://files.vxv.INTERNAL/$1@){}
elsif
($url=~s@^http://(.*?)megaupload\.com/files/(.*?)/(.*?)@squid://files.megaupload.INTERNAL/$3@){}
elsif
($url=~s@^http://(.*?)mediafire\.com/(.*?)/(.*?)@squid://files.megaupload.INTERNAL/$3@){}
elsif
($url=~s@^http://(.*?)depositfiles\.com/(.*?)/(.*?)/(.*?)@squid://files.megaupload.INTERNAL/$4@){}
elsif
($url=~s@^http://(.*?)\.files\.youporn\.com\/(.*?)\/([0-9a-zA-Z_-]*?\.flv)\?.*@squid://videos.youporn.INTERNAL/$3@){}
elsif
($url=~s@^http://(.*?)\.tube8\.com\/(.*?)\/([0-9a-zA-Z_-]*?\.flv)\?.*@squid://videos.tube8.INTERNAL/$3@){}
elsif
($url=~s@^http://(.*?)\.tube8\.com\/(.*?)\/([0-9a-zA-Z_-]*?\.flv)@squid://videos.tube8.INTERNAL/$3@){}
elsif
($url=~s@^http://(.*?)megaporn\.com\/files\/(.*?)\/(.*?)@squid://files.megaporn.INTERNAL/$3@){}
print "$url\n"; }
Initialize squid swap directories
mkdir /var/cache/squid chown squid.squid /var/cache/squid /opt/squid/sbin/squid -z
Create log folder
mkdir /var/log/squid chown squid.squid /var/log/squid
/etc/rc.d/init.d/squid
#!/bin/bash
### BEGIN INIT INFO
# Provides: squid
# chkconfig: - 90 25
# pidfile: /var/run/squid.pid
# config: /opt/squid/etc/squid.conf
# Short-Description: starting and stopping Squid Internet Object Cache
# Description: Squid - Internet Object Cache. Internet object caching is \
# a way to store requested Internet objects (i.e., data available \
# via the HTTP, FTP, and gopher protocols) on a system closer to the \
# requesting site than to the source. Web browsers can then use the \
# local Squid cache as a proxy HTTP server, reducing access time as \
# well as bandwidth consumption.
### END INIT INFO
PATH=/usr/bin:/sbin:/bin:/usr/sbin
export PATH
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
#if [ -f /etc/sysconfig/squid ]; then
# . /etc/sysconfig/squid
#fi
# don't raise an error if the config file is incomplete
# set defaults instead:
SQUID_OPTS=${SQUID_OPTS:-"-D"}
SQUID_PIDFILE_TIMEOUT=${SQUID_PIDFILE_TIMEOUT:-20}
SQUID_SHUTDOWN_TIMEOUT=${SQUID_SHUTDOWN_TIMEOUT:-100}
# determine the name of the squid binary
#[ -f /opt/squid/sbin/squid ] && SQUID=squid
SQUID=/opt/squid/sbin/squid
if [ $1 == 'status' ]; then
[ -z "$SQUID" ] && exit 4
else
[ -z "$SQUID" ] && exit 1
fi
prog="$SQUID"
# determine which one is the cache_swap directory
CACHE_SWAP=`sed -e 's/#.*//g' /opt/squid/etc/squid.conf | \
grep cache_dir | awk '{ print $3 }'`
[ -z "$CACHE_SWAP" ] && CACHE_SWAP=/var/spool/squid
RETVAL=0
probe() {
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 1
# check if the squid conf file is present
[ -f /opt/squid/etc/squid.conf ] || exit 6
}
start() {
probe
for adir in $CACHE_SWAP; do
if [ ! -d $adir/00 ]; then
echo -n "init_cache_dir $adir... "
$SQUID -z -F -D >> /var/log/squid/squid.out 2>&1
fi
done
echo -n $"Starting $prog: "
$SQUID $SQUID_OPTS >> /var/log/squid/squid.out 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
timeout=0;
while : ; do
[ ! -f /var/run/squid.pid ] || break
if [ $timeout -ge $SQUID_PIDFILE_TIMEOUT ]; then
RETVAL=1
break
fi
sleep 1 && echo -n "."
timeout=$((timeout+1))
done
fi
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$SQUID
[ $RETVAL -eq 0 ] && echo_success
[ $RETVAL -ne 0 ] && echo_failure
echo
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
$SQUID -k check >> /var/log/squid/squid.out 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
$SQUID -k shutdown &
rm -f /var/lock/subsys/$SQUID
timeout=0
while : ; do
[ -f /var/run/squid.pid ] || break
if [ $timeout -ge $SQUID_SHUTDOWN_TIMEOUT ]; then
echo
return 1
fi
sleep 2 && echo -n "."
timeout=$((timeout+2))
done
echo_success
echo
else
echo_failure
echo
fi
return $RETVAL
}
reload() {
$SQUID $SQUID_OPTS -k reconfigure
}
restart() {
stop
start
}
condrestart() {
[ -e /var/lock/subsys/squid ] && restart || :
}
rhstatus() {
status $SQUID && $SQUID -k check
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
restart
;;
condrestart)
condrestart
;;
status)
rhstatus
;;
probe)
probe
return 0
;;
*)
echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|probe}"
exit 2
esac
exit $?
Install squid service
chmod +x /etc/rc.d/init.d/squid chkconfig --add squid chkconfig squid on service squid start
This setup enable users to log in to remote machine without having to enter their password.
On local machine, generate public/private key pair:
ssh-keygen -t rsa
or use PuTTYgen
Send to remote machine:
cat ~/.ssh/id_rsa.pub | ssh user@domain "cat - >> ~/.ssh/authorized_keys"
or
scp ~/.ssh/id_rsa.pub user@domain:~/.ssh/authorized_keys
or use WinSCP
Note: when generating public keys using puttygen, reorganize the file content:
ssh-rsa <pub key string> user@domain # in one line
<pub key string> is:
--- BEGIN ... Comment: ... <pub key string> --- END ...
Set permission:
chmod 600 ~/.ssh/authorized_keys
To login from local machine:
ssh user@domain # automatically logged in, no password prompt
or using PuTTy:
Extra, SSH server configuration tweak (change those config values).
vim /etc/ssh/sshd_config
PermitRootLogin no PasswordAuthentication no
This is multiple projects installation, a continuation from previous posts.
Install required packages:
yum install trac mod_wsgi
Software: Trac 0.11.7, mod_wsgi 2.3
Trac folder: /var/svn/trac
Python eggs cache dir: /tmp/egg-cache
Create new trac environment
trac-admin /var/svn/trac/testproj initenv Project Name > Test Project Database connection string > [sqlite:db/trac.db] Repository type > [svn] Path to repository > /var/svn/repos/testproj
Create wsgi script
vim /var/svn/trac/trac.wsgi
#!/usr/bin/env python import os def application(environ, start_request): os.environ['TRAC_ENV_PARENT_DIR'] = '/var/svn/trac' os.environ['PYTHON_EGG_CACHE'] = '/tmp/egg-cache' from trac.web.main import dispatch_request return dispatch_request(environ, start_request)
Apache mod_wsgi settings
vim /etc/httpd/conf.d/trac.conf # comment all settings in /etc/httpd/conf.d/wsgi.conf
LoadModule wsgi_module modules/mod_wsgi.so
WSGIScriptAlias /trac /var/svn/trac/trac.wsgi
<Directory /var/svn/trac>
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<LocationMatch "/trac/[^/]+/login">
AuthType Digest
AuthName "Project Repository"
AuthUserFile /var/svn/auth
Require valid-user
</LocationMatch>
Grant administration right to admin user (trac>=0.11)
trac-admin /var/svn/trac/testproj permission add user1 TRAC_ADMIN
Set ownership
chown -R apache.apache /var/svn
Reload apache
service httpd reload
View list of projects - http://localhost/trac
Recent Comments