Wednesday, May 4, 2011

Methods to Increase Security on suPHP - Restricting who can use php.ini files

SkyHi @ Wednesday, May 04, 2011
The php.ini file under suPHP

While suPHP has various security enhancements over DSO PHP such as running processes as the user rather than nobody as well as only allowing 755 folder and 644 file permissions, the option to allow individual php.ini files is a glaring security concern.

There are several methods that can be used to disallow users to have their own php.ini files under suPHP. The path you take will depend on whether you want to allow users to have their own in some circumstances or to restrict all accounts on the server to the global php.ini file at /usr/local/lib/php.ini location.

Restrict all accounts to the global php.ini file

To restrict all accounts to the global php.ini file, you would edit the /opt/suphp/etc/suphp.conf file:

Uncomment these lines:

;Uncommenting these will force all requests to that handler to use the php.ini
;in the specified directory regardless of suPHP_ConfigPath settings.
To these:

;Uncommenting these will force all requests to that handler to use the php.ini
;in the specified directory regardless of suPHP_ConfigPath settings.
Save the file, then restart Apache for good measure. Now, if any account tries to put suPHP_ConfigPath into their .htaccess file, that account will return an Internal Server Error until they remove the .htaccess line. No account will be able to use another php.ini file with this as the default unless you allow the account in the php.ini file itself.

If you have PHP 5.3+ and want to allow some accounts to have their own php.ini file

If you have restricted all accounts globally to the /usr/local/lib/php.ini file and want to have one or more accounts bypass the restriction, this is possible under PHP 5.3 using the global php.ini itself.

Method One: Allowing individual user_ini files

In /usr/local/lib/php.ini file, put the following line:

user_ini.filename = .my.ini
The .my.ini name can be anything. Save the file, then go to the account you want to allow their own settings and create .my.ini on the account (it can be anywhere on the account so /home/username/public_html/.my.ini)

In the .my.ini file, you would be able to put only the changes you want to have such as register_globals = On for that account. Of note, only the PHP_INI_PERDIR and PHP_INI_USER directives are allowed in this file. Any PHP_INI_SYSTEM directives will not be changeable there.

Method Two: Putting individual user settings into the global php.ini file

This is the better method in my opinion. At the bottom of /usr/local/lib/php.ini file, you can actually define individual user php.ini directives with the path to that user's application:

Here is an example putting that at the bottom of /usr/local/lib/php.ini for an account. If you try doing this in PHP 5.2, it will change the global value to the new ones rather than just that user's as PHP 5.2 doesn't support the path directive. Only PHP 5.3 will work properly to read the path to the user's application. Under this method, even PHP_INI_SYSTEM directives are changeable for that account.

Under Method One for the user_ini file, the user does have the ability to themselves modify directives in their .my.ini file on the account. Under Method Two for the global php.ini user path directives, only the administrator of the machine could modify the directives. Of note, anyone can create their own user_ini file under Method One, but they would need to know the name in the global php.ini to do so (since you can call the file anything, so it could be called .guessme.ini instead and users aren't then likely to know the name to bypass restrictions).

If you are using PHP 5.2 or earlier (PHP 5 only, not tested on PHP 4 nor guaranteed to work on PHP 4)

If you are not using PHP 5.3, then the prior methods will not work. This then leads instead to the more complicated option to allow some users to have their own php.ini file and some users to be restricted to the global php.ini file.

Under this method, you cannot have the phprc_paths uncommented, so you must have them commented out. As such, you would need to ensure /opt/suphp/etc/suphp.conf looks like the following for that area:

;Uncommenting these will force all requests to that handler to use the php.ini
;in the specified directory regardless of suPHP_ConfigPath settings.
Now, you would need to do the following steps:

1. Restrict all users to the global php.ini

Create the following directory:
mkdir -p /usr/local/apache/conf/userdata
Create a file in that directory:
cd /usr/local/apache/conf/userdata
vi suphp_config.conf
In that file, place the following:

suPHP_ConfigPath /usr/local/lib

Save the file (:wq). The above will restrict all current users to the /usr/local/lib location for the php.ini file.

2. Allowing one user to have an individual php.ini

Create the following directories:
mkdir -p /usr/local/apache/conf/userdata/std/2/username
Here, std is for http. If you are also wanting this for https, you'd also create an ssl directory. The 2 is for Apache 2 and 2.2. If you are using Apache 1.3, you'd use 1 instead. The username is the cPanel username, so replace with the correct username.

In that location, create the file:
cd /usr/local/apache/conf/userdata/std/2/username
vi suphp_config.conf
In that file, place the following:

suPHP_ConfigPath /home/username/

Again, replace username with the cPanel username. This will allow a php.ini file to be placed into /home/username level only. Save the file (:wq).

3. Adding additional directories

Further directories can be allowed on the user's account who is being allowed to have a php.ini file. If you change the entry to this in
/usr/local/apache/conf/userdata/std/2/username/suphp_config.conf location:


suPHP_ConfigPath /home/username/{public_html}/{folder1,folder2}

This allows a php.ini in public_html as well as in public_html/folder1 and public_html/folder2 locations.

4. Checking the changes into httpd.conf

Create a backup of Apache in case you need to revert to it:
cp /usr/local/apache/conf/httpd.conf
Here 100902 is the date where today is September 2, 2010.

Now, run the following command to verify the includes:
If each checks out OK, you'd then run this command to check these into the system:
/scripts/ensure_vhost_includes --all-users
Now, rebuild Apache and restart it (rebuilding isn't entirely necessary in this instance, but I normally just do it as a precaution to ensure everything is working fine):
/etc/init.d/httpd restart
Two Important Notes on Above Method

1. mod_userdir exception

mod_userdir will bypasses the suPHP_ConfigPath restriction for the global php.ini file. If you have a user with the following url type:


That url will allow any php.ini files or suPHP_ConfigPath set into .htaccess to parse under mod_userdir. This is unwanted behavior, and the only current way I'm aware to prevent it would be to disable mod_userdir on such a system.

2. New accounts aren't restricted

Any accounts created after you have locked users into the global php.ini file using the tags around suPHP_ConfigPath in userdata location will not be restricted to it. Each time a new account is created, the following must be run after the account creation to lock that account to the global restriction:

/scripts/ensure_vhost_includes --all-users
/etc/init.d/httpd restart
Final Note: suPHP_ConfigPath in httpd.conf

Defining the suPHP_ConfigPath line in the VirtualHost entry in httpd.conf does not restrict the account to using that path if the tags are not around it. Without those tags, if a user defines the suPHP_ConfigPath into their .htaccess file on their account in either /home/user/ or /home/user/public_html, their .htaccess entry will override the httpd.conf VirtualHost entry. You can only lock users to the set suPHP_ConfigPath by the previously described method.


apache2 with suPHP and php 5.3 along side php 5.2

SkyHi @ Wednesday, May 04, 2011
The idea is this one: Stay up2date with Ubuntu’s packages (currently they stick with the latest php version available) but still provide old php as a standalone with suPHP – both increasing security and compatibility.
So the software that i’ve got: Ubuntu 10.04.2 (lucid), apache2 (v.2.2.14), php 5.3 (v.5.3.2-1ubuntu4.7), suPHP 0.7.1,  php 5.2 (v.5.2.17).
let’s start.

1st step – get and configure apache2, php, phpmyadmin normally on your Ubuntu box (i have mine already setup so i’ll be skiping this step – you could check howtoforge for tutorials).

2nd step – get suPHP and configure it – i did it manually thus sticking to the latest available release:

./configure --disable-checkpath --disable-check-docroot --prefix=/usr --sysconfdir=/etc/apache2 --with-apache-user=www-data --with-setid-mode=paranoid --with-apxs=/usr/bin/apxs2 --with-php=/usr/bin/php-cgi -with-logfile=/var/log/suphp.log --with-apr=/usr/bin/apr-1-config --enable-SUPHP_USE_USERGROUP=yes

make;make install

rm -rf /etc/apache2/mods-available/php5.load /etc/apache2/mods-enabled/php5.load

(removed the php5.load’s because in my case apache would ignore suPHP)

edit /etc/apache2/httpd.conf and add

LoadModule php5_module /usr/lib/apache2/modules/
LoadModule suphp_module /usr/lib/apache2/modules/

I’ve choosed to load php5_module also so that if i ever forget to config suPHP .php’s sould still work.
now here’s my suPHP config:


now you will face a certain suPHP issue with phpmyadmin as it’s owned by root (when installed with apt-get) thus

chown -R www-data:www-data /usr/share/phpmyadmin

and now i’ve setup it as a subdomain and suPHPed it (at a hoster level this can be a issue as users need to access the phpmyadmin via they’r domain – a fix would be to skip suPHP for phpmyadmin and alias it):

DocumentRoot /usr/share/phpmyadmin
#Alias /phpmyadmin /usr/share/phpmyadmin
suPHP_Engine on
suPHP_UserGroup www-data www-data
AddHandler x-httpd-suphp .phpsu
PHP_AddHandler x-httpd-suphp

Options Indexes FollowSymLinks
DirectoryIndex index.php

AddType application/x-httpd-php .php
php_flag magic_quotes_gpc Off
php_flag track_vars On
php_flag register_globals Off
php_value include_path .

# Disallow web access to directories that don't need it

Order Deny,Allow
Deny from All

Order Deny,Allow
Deny from All

step 3 – get php 5.2 configure it and enjoy

./configure --prefix=/usr/local/php5.2 --enable-fastcgi --enable-force-cgi-redirect --disable-cli --enable-discard-path --with-config-file-path=/usr/local/php5.2/config --without-pear --with-openssl=/usr --with-iconv --with-curl --with-mysql --with-mysqli --enable-mbstring --enable-exif --with-jpeg-dir --with-zlib --with-zlib-dir --with-png-dir --with-gd --with-gettext --enable-gd-native-ttf --with-mhash --with-mcrypt --enable-bcmath --with-mime-magic --with-pdo-mysql --enable-sockets --enable-xml --enable-libxml --enable-dom --enable-simplexml --enable-xmlreader --enable-xmlwriter

i’ve found some missing libs regarding jpg, png, mcrypt and mhash thus -

apt-get install libcurl3-dev
libjpeg8-devlibjpeg62-dev libpng3-dev libmcrypt-dev libmhash-dev

before continuing you might want to keep a copy of (the php5.3 one) before it get’s replaced by php5.2′s make install

cp /usr/lib/apache2/modules/ /usr/lib/apache2/modules/

so if you decide to keep php5.3 for the non-configured virtual hosts you could always load that in apache LoadModule

make; make install

go to /etc/apache2/suphp.conf and edit it to use php5.2 to
find x-httpd-suphp and after it add:


so here’s a apache virtual host that uses both php5.3 and php5.2 in the same time:

DocumentRoot /home/bogdan/sites/phps.pvp.roServerName
CustomLog     /var/log/apache2/ combined
ErrorLog      /var/log/apache2/
LogLevel warn

suPHP_Engine on
suPHP_UserGroup bogdan bogdan
AddHandler x-httpd-suphp .php
suPHP_AddHandler x-httpd-suphp
AddHandler x-httpd-suphp52 .php52
suPHP_AddHandler x-httpd-suphp52

you will probably need only one handler for .php so assign the .php to x-httpd-suphp52
now it’s suhosin’s turn to be configured with php5.2 (this step i will go fast)

mv  /etc/alternatives/php /etc/alternatives/php5.3
mv  /etc/alternatives/phpize /etc/alternatives/phpize5.3
mv   /etc/alternatives/php-config /etc/alternatives/php-config5.3
ln -s /usr/local/php5.2/bin/php-cgi  /etc/alternatives/php
ln -s /usr/local/php5.2/bin/php-config  /etc/alternatives/php-config
ln -s /usr/local/php5.2/bin/phpize /etc/alternatives/phpize
tar xzvf  suhosin-
cd suhosin-
mv ./modules/ /usr/local/php5.2/lib/php/extensions
~add to /usr/local/php5.2/config/php.ini : ~

attention! i’ve moved the original  /etc/alternatives/phpize to /etc/alternatives/phpize5.3 and and php-config so that when i phpize and configure the suhosin it would be setup for php5.2 (/usr/bin/phpize beeing linked to /etc/alternatives/phpize) you might want to move them back, or not…
hope this post helps!
sources:, apache,, suphpJakub Suchý
p.s. watch the phpinfo’s as they provide interesting security options for suhosin


SMTP server on Windows 7

SkyHi @ Wednesday, May 04, 2011
1.Since I needed this only for development, I ended up using smtp4dev, which is exactly what you need when developing an application that sends emails.
The project description:
Dummy SMTP server that sits in the system tray and does not deliver the received messages. The received messages can be quickly viewed, saved and the source/structure inspected. Useful for testing/debugging software that generates email.

2.hMailServer is the easiest way to get an SMTP service running on Windows 7 and Vista.

Tuesday, May 3, 2011


SkyHi @ Tuesday, May 03, 2011
What is NAT?
NAT (Network Address Translation) is a technology most commonly used by firewalls and routers to allow multiple devices on a LAN with 'private' IP addresses to share a single public IP address. A private IP address is an address, which can only be addressed from within the LAN, but not from the Internet outside the LAN. In order to let a device with a private IP address communicate with other devices on the Internet, there needs to be a translation between private and public IP addresses at the point where the LAN connects to the Internet, that is within the firewall/router connecting the LAN to the Internet. Such a translation is commonly referred to as NAT (for Network Address Translation) and a router doing such translation is often called a NAT router or NAT firewall/router. Sometimes NAT is also called IP Masquerading. The passing of traffic through NAT is called NAT Traversal.

The way NAT works is in principle rather simple. When a device on the LAN initiates a connection with a device on the Internet, the device will send all traffic to the NAT router first. The NAT router then replaces the source address, which is the device's private address, with its own public address before passing the traffic to its destination on the Internet. When a response is received, the NAT router searches its translation tables to find the original source address of the packet from which the device on the LAN originally started the connection and thus passes the response to that device.

Unfortunately, when a connection is originated by a device on the Internet outside the LAN it is not clear which device on the LAN the connection is meant to be established with. In this case there needs to be some rule that tells the NAT router what to do with the incoming traffic, otherwise it will simply discard the traffic and no connection will be established. If the NAT router supports what is commonly referred to as a 'software DMZ' it can handle simple rules, such as "pass all incoming connection requests to the device with address". Another technique, called port forwarding allows the NAT router to pass incoming connection requests to different devices on the LAN depending on the type of connection (ie web or mail connection). However, if there are multiple devices on the LAN to which a certain type of connection from outside may need to be established, then neither a software DMZ nor port forwarding will be sufficient.

Sometimes people (those without network experience) have difficult to understand if their host is or not behind NAT, there is a website that will test to see if you are behind NAT (you need to have Java): (

The Trouble with NAT and VOIP
In addition, the way in which conventional VoIP protocols are designed is also posing a problem to VoIP traffic passing through NAT. Conventional VoIP protocols only deal with the signalling of a telephone connection. The audio traffic is handled by another protocol and to make matters worse, the port on which the audio traffic is sent is random. The NAT router may be able to handle the signalling traffic, but it has no way of knowing that the audio traffic is related to the signalling and should hence be passed to the same device the signalling traffic is passed to. As a result, the audio traffic is not translated properly between the address spaces.

At first, for both the calling and the called party everything will appear just fine. The called party will see the calling party's Caller ID and the telephone will ring while the calling party will hear a ringing feedback tone at the other end. When the called party picks up the telephone, both the ringing and the associated ringing feedback tone at the other end will stop as one would expect. However, the calling party will not hear the called party (one way audio) and the called party may not hear the calling party either (no audio).

The issue of NAT Traversal is a major problem for the widespread deployment of VOIP. Yet, the issue is non-trivial and there are no simple solutions. In general terms there are two ways to deal with this problem:

avoid the problem altogether
working around the problem

By far the best way to deal with the issue of VoIP NAT Traversal is to avoid the cause of the problem in the first place:

Do not use NAT and obtain public IP addresses for all VoIP devices
If you cannot avoid NAT, use IP Tunneling between VoIP devices on different LANs
Use a public service. Eg sign up both sides to FWD and call from one to the other. Look at user authentication page for ways to control who has access to your internal lines
Use servers that implement IETF's Best Current Practices for NAT Traversal for Client-Server SIP. One of those is Yate

If you cannot avoid the problem, there are still several techniques available to work around the problem, none of them without their downsides. A white paper (NAT Traversal in SIP) explains some of the issues (at least as they relate to SIP signaling) and discusses STUN- & ICE-based workarounds in more detail.
fridu has published a set of clarifications and a step by step solution to interconnect an Asterisk server and remote SIP phones over a dual NAT configuration. You will find it on web site.

However, there are some simple workarounds available:

(Re) Configure your NAT device to provide (limited) VoIP support. The specific configuratios required depend on what is required by the signaling method used (e.g. SIP, H.323, etc.) and the number and type of devices inside your NAT, and are set using the specific user interface supplied by your NAT vendor.
For instance, to set up a single SIP phone inside a residential NAT:
Set the SIP phone up with a static IP address;
Set up two forwarding entries the "Port Forwarding" (or similar) configuration form on the NAT configuration interface, each of which cause the NAT device to forward all traffic destined for the designated range of port numbers to the fixed IP address of the SIP phone:
SIP signaling: Ports 5060 to 5070
RTP audio: Ports 8766 to 35000
For enterprise firewalls, many directly support SIP and H.323 forwarding to both Proxy/PBX devices as well as to/from VoIP phone endpoints
Use a VoIP Protocol that overloads HTTP in order to traverse NATs on normally-open IP ports, such as the open IAX protocol. (Caution: IP network protocol experts will point out that techniques such as this which use HTTP for purposes for which it was not intended frequently carry negative unintended side-effects.)
A utility is available that enables Asterisk (win32) to work on the same box as ISA Server. and look for SIPPF in the downloads area. It's a free script.
IXC found an approach to enable NAT customers to be callable via h323. It's possible to test this 'know how' after registration. News release of new version is also available.
Linux kernel: Netfilter seems to have got a conntrack patch for sip/rtp nat/firewall traversal: Iptables sip conntrack

'different approaches for making sip devices work behind a dd-wrt router'

'dd-wrt v23sp1voip' - upgrade your dd-wrt compatible router to dd-wrt v23sp1 (didn't test sp2 yet) VOIP version

This software release includes a special version of the ser (sip express router) software, which is able to act as an outbound proxy for sip devices (almost like a http proxy does for webbrowsers). ser and the second component rtpproxy take care of registering clients on the private network and forward all trafic between the sip service provider and the internal client (sip messages and rtp media streams).

This solution works fine for any device that has "outbound proxy" support as many ata (e.g. linksys-sipura spa 2001, grandstream budgetone etc.) do.

Just enter the ip adress and sip port (see dd-wrt administration interface for ip/port) of your dd-wrt router as outbound proxy in your phone's configuration screen. Restart the phone, and voila, you can talk. This works for an unlimited number of phones, as long as each phone uses a different sip username. Using the same sip username e.g. on a two analoge port sipura ata for both analog ports causes the second port to get registered to not work for incoming calls (not 100 % verified - please let me know if you tested it).

'transparent proxy on dd-wrt/openwrt'

Me myself having trouble using sip devices without "outbound proxy" support behind my dd-wrt routers, I was searching for a more simple solution. My motivation was to have booth my asterisk box behind the router as well as my nokia e61 sip smartphone being able to register to out companies public sip server. This was not possible as both asterisk as well as the current nokia sip client don't support outbound proxy nor stun.

Having used transparent proxies for hhtp for a while, the question was, why not do the same for sip messages and the rtp media streams? Well, it's possible. I didn't actually figure it out using dd-wrt voip's built in ser/rtpproxy package (maybe it's possible too with them), but relied on the instructions i found for the software "sipproxd" which is luckily available for the mips based broadcom plattform (openwrt package).

What you basically need is:

- dd-wrt/openwrt (non voip firmeware version - tested with v23sp1) with jffs enabled (and enough spare memory - this solution does not work for 8mb and maybe also not for 16 mb broadcom based router models). I myself us a 32mb Linksys WRT54GS v1.1. You need JFFS as a filesystem to download, install and configure additional software packages useing ipkg.
- ssh/telnet access to your router
- the information available on

First enable jffs and initialize ipkg (see other dd-wrt/openwrt faqs/howtos on how to do this in detail). Once you've done this log onto your router using telnet or better ssh (root/).

Then download the siproxd package using the command "ipkg install siproxd". Then follow the instructions on this manual page

You've to create the config file using the editor "vi" on while being looged onto your router. Copying the Text from the webrowser to the console vi using putty can be quite a hassle as for some reason characters seem to move to other places whil in reality they are still on their old place in the textfile. To be sure, save the file often, then open it again to get a clean view and then copy the next part of the file.

Then start siproxd by calling it from the command line cd ... then ./siproxd -c .

Finally copy the iptables commands one after each other to the console. Then fire up your sip client with it being configures as if it had a public ip address (e.g. etc.) and voila you can talk and you be reachable if someone is calling you.

Currently the solution is not 100 % stable, as my nokia e61 is registering with my public asterisk server sucessfully the first time, but not the second time once I lost wlan connectivity. I did not determine yet if it is a problem on the router/siproxd or if it was the due to nokia e61 software problems (I then had the branded april/2006 software version in the phone. I have not tried it with the generic nokia 07/2006 version yet as I found an even better solution for my nokia which I'll describe below.

'Mobile IPv4/Birdstep SmartRoaming'

The sipproxd solution works fine for clients within a fixed wlan/lan network. But what about poor me using my nokia outside my home/office network. It's nearly impossible to have all routers's equipped with siproxd transparent proxy solution.

After searching for a long time and having spent hours with Nokias incomplete SIP/Network Group Roaming implementation, I found a software supporting the Mobile IPv4 RFC on symbian operating systems. Great, what it basically does is having a client installed on your mobile phone, which makes a new connection available to all applications. It works like a vpn/tunnel. Thus once any network connection is available, the software signs up and creates a tunnel to Birdstel/Smartroaming and your phone gets a public IP from them.

Now it also takes care of you allways using the best connection, thus it's scanning for the wlan networks you've defined, and once you enter the office, it automatically sends all traffic via the wlan, or grps/umts vice versa when you leave the office. The applications are ALLWAYS ONLLINE and don't notice the connection change which is taking place in the background.

The best thing, there's no NAT, all applications are using the phones public ip via the tunnel. Thus your SIP client works flawlessly being able to register with my asterisk, sipgate and probably many other sip providers without any problem. Works like a charm.

The only drawback: after 1 month free trial, you've to pay a yearly fee of ~30 eur if you're using their Mobile IPv4 service. The say you can use the software (once you buy a licence) with other providers too. Too bad all open source software in regard to Mobile IPv4 is completely outdated and so to my knowledge no alternative option of being your own Mobile IPv4 Provider exists (apart from commercial software from hp/cisco etc.).

Some vendors offer information on the problem, and on how you can use their products to address the problem:

SNOM white paper: Operating phones behind NAT whitepaper: VOIP traversal of NAT and firewall
White Paper: The SIP Protocol and Firewall Traversal
Newport Networks White Paper NAT Traversal for Multimedia over IP
White Paper: NAT Traversal for VoIP and Internet Communications using STUN, TURN and ICE
Use a SIP- and RTP-Proxy combination on your NAT/Firewall/Router - as done by the SIPatH Project

Free SIP NAT Solutions

Xtunnels Free NAT solution from Counterpath. Works with all Xlite and Eybeam softphones.

Other NAT Solutions
Some vendors offering NAT traversal 'solutions' for VOIP:

Acme Packet
AG Projects
BorderWare Technologies Inc.
CommuniGate Systems
Cylogistics Trueline Session Border Controller
Eyeball Networks AnyFirewall Server and SDK
Data Connection
FreeSwitch opensource server that avoids most NAT issues by design
Jasomi Networks
Kagoor Networks
Loongtek: p2p nat tunnel library
MailVision's NAT Traversal Solutions
Mera Systems
miniSipServer for windows.
Newport Networks
OpenSBC Open source Session Border Controller
Voice SIstem

See also:

A basic explanation of STUN protocol
Avoid SIP NAT Traversal using the NAT friendly IAX protocol
Asterisk: How to connect to FWD: Examples on Asterisk and NAT (to/from FWD )
Asterisk SIP NAT solutions
Freshmeat Article on SIP and NAT
How to solve the NAT traversal issue in SIP?
ICE: Interactive Connectivity Establishment (a proposal for NAT and SIP)
Important thing to look at if you get one way audio problem with Asterisk 1.4.10 and FreePBX 2.3.0
NAT survey: Types of NAT in various equipment
NAT Traversal for VoIP and Internet Communications using STUN, TURN and ICE - white paper
quintum VoIP gateways NAT Traversal ready
SER NAT support: How SIP Express Router supports NAT (Interesting solution - check nathelper!)
Sho voip phone on SIP ,NAT and dect phones.
STUN: Simple Traversal of UDP through NAT
STUN protocol and VOIP A technical explanation of the purpose of STUN protocol in VOIP scenarios.
VOIP Routers


Global Find and Replace In WordPress using MySQL phpmyadmin

SkyHi @ Tuesday, May 03, 2011
In case you ever need to find and replace a text string in every post or page of your WordPress site, this SQL code will help you out. I recently had to move a client’s website from staging into production, and just when I was getting ready to publish the new site I realized WordPress’s HTML editor had hard-coded the URLs of every image in every post to the address of the staging server.  This is actually a feature of WordPress; when you upload an image into a post or page it uses an absolute URL, not a relative one.  This really helps you out if any of your posts get picked up via RSS and published elsewhere, since the images will remain intact thanks to the absolute URLs.
NOTE: An absolute URL is the fully qualified path to a resource; such as  A relative URL will only work when the file is relative to the path of the current page, such as ../images/image.jpg.
So here I was with a couple hundred pages of content with image URLs all pointing to the wrong address on the staging server.  I needed a quick way to do a find and replace on every post in the WordPress MySQL database.  It was actually pretty simple.  In my case, I just had to execute this SQL code against the MySQL WordPress database:

UPDATE wp_posts SET post_content = REPLACE(post_content, '', '');

This code will search through every “post_content” field in the wp_posts table and replace the staging URL address ( with the production address (  The format is easy to understand and can of course be used with any MySQL table, not just WordPress:

UPDATE [your_table_name] SET [your_table_field] = REPLACE([your_table_field], '[string_to_find]' , '[string_to_be_replaced]');

I realize this isn’t the most complex or enlightening code sample, but I hope this helps anyone stuck with an annoying repetitive text string in all your WordPress posts which you’d like to search and replace with one quick command.

This is a life-saver: an easy way to search any table inside your database and replace one string of text with another. It works like a charm. But be careful, search first to see the results of your query before you commit the changes, and always backup prior to any database work.
Here is how you test the waters safely:
SELECT * FROM `wp_posts` WHERE `post_content` LIKE '%oops%'
SELECT * FROM `table_name` WHERE `field_name` LIKE '%unwanted_text%'
And here is how you do some damage:
UPDATE `wp_posts` SET `post_content` = replace(post_content, 'oops', 'much better')
And translated:
UPDATE `table_name` SET `field_name` = replace(same_field_name, 'unwanted_text', 'wanted_text')

Search and Replace in MySQL database with phpMyAdmin

Do a search and replace in any MySQL database in phpMyAdmin. You do not need to download the database export at all, just run this simple command. This also works through the MySQL command line.
To search and replace a text string, start up phpMyAdmin, and click on your database name that you want to run the search and replace through. At the top of the window, click on the "SQL" tab.
In the text box, enter the following code. This is the generic setup, so edit to satisfy your needs:

UPDATE tablename SET tablefield = replace(tablefield,"findstring","replacestring");

You can add a WHERE clause onto this as well.
For example, here is one command a ran:

UPDATE `mos2_content` SET introtext = replace(introtext,"<p>
","") WHERE `title` REGEXP '-0';

This got rid of all paragraph tags in the mos2_content table where the title included the string "-0".
Hope this helps. If you have any comments, suggestions, questions, or your own code, please submit a comment below.


Monday, May 2, 2011

How to find the largest files on Windows?

SkyHi @ Monday, May 02, 2011

Windows XP

  1. Go to Start / Search / For Files or Folders
  2. Select the search option All Files and Folders
  3. Enter *.* in the file name search box
  4. Select the hard drive(s) you would like to search
  5. (Optional) Select the What size is it? option and choose Large
  6. Click the Search button
  7. Click the Size column to sort the results


Check your disk usage with df and du

SkyHi @ Monday, May 02, 2011
As system administrator , but also as common user on my PC, one of the more common problem is the fill up at 100% of a filesystem.
So, in this article we’ll see 2 commands that can help us in keeping under control or check the space used in every filesystem and in his directory.
df : report file system disk space usage
du: estimate file space usage


Basic usage

df [Option...] [FILE_NAME...]
If [FILE_NAME...] is not given df displays the following information for each file system that was activated with mount: total space, used space, free space and use in %.
if it’s given [FILE_NAME...] the same information is given for the filesystem containing the specified files .
The most used options for df are -k that show the output values in Kilobytes (this is usually teh default), -h that print sizes in human readable format (e.g., 1K 234M 2G) and -i that give information about inodes
Filesystem           1K-blocks      Used Available Use% Mounted on
                       4128448    400936   3517800  11% /
                        516040     17568    472260   4% /home
                       4128448    164316   3754420   5% /tmp
                       8256952   1240372   6597152  16% /usr
                       4128448    490632   3428104  13% /var
                       8256952    320836   7516740   5% /var/log

Same machine but with the -h option:
#df -h
Filesystem            Size  Used Avail Use% Mounted on
                      4.0G  392M  3.4G  11% /
                      504M   18M  462M   4% /home
                      4.0G  161M  3.6G   5% /tmp
                      7.9G  1.2G  6.3G  16% /usr
                      4.0G  480M  3.3G  13% /var
                      7.9G  314M  7.2G   5% /var/log

Same machine but with the -i option:
#df -i
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
                        256K    7.0K    250K    3% /
                         32K      55     32K    1% /home
                        256K      27    256K    1% /tmp
                        512K     51K    462K   10% /usr
                        256K    4.0K    253K    2% /var
                        512K     473    512K    1% /var/log

An example a bit more interesting, we do a df, then we use the ouput to see when is the next check of the filesystem (it works on ext3 /4):
df  | awk '{print $1}' | grep dev\/ | xargs -i tune2fs -l {}| egrep "mounted|Next"
Last mounted on:          /
Next check after:         Sat Oct  1 19:05:57 2011
Last mounted on:          /home
Next check after:         Sat Oct  1 12:33:16 2011
Last mounted on:          /tmp
Next check after:         Sat Oct  1 19:06:00 2011
Last mounted on:          /usr
Next check after:         Sat Oct  1 19:06:04 2011
Last mounted on:          /var
Next check after:         Sat Oct  1 19:06:07 2011
Last mounted on:          /var/log
Next check after:         Sat Oct  1 12:33:22 2011




Basic usage

du [Option...] [FILE_NAME...]
The du command serves to return the size of either an entire file system or a folder, file, etc..
du command returns the size of each file and directory that is within that directory. If [FILE_NAME...] is not given du will print the disk usage of every file from the current directory and all subdir.
You can use the option -a , which tells the du command to return the size of individual files and directories, while -s display only a total for each argument.
Another important parameter is -h which makes the output, of the du command, more friendly to the human eye such as 18M instead of displaying 17,532 (the same number shown in bytes without rounding).
Another recommended setting is -c which returns the total size of all files.

Show the disk usage of /var
# du -hs /var/
481M /var/

Show the disk usage of every directory in /var and print the total:
# du -hsc /var/*
5.3M /var/backups
188M /var/cache
112M /var/lib
4.0K /var/local
16K /var/lock
177M /var/log
16K /var/lost+found
12K /var/mail
4.0K /var/opt
100K /var/run
604K /var/spool
4.0K /var/tmp
120K /var/www
481M total

Get the 10 biggest files/folders for the /var/ directory
# du -s /var/* | sort -nr |head
191676 /var/cache
180760 /var/log
113712 /var/lib
5332 /var/backups
604 /var/spool
120 /var/www
100 /var/run
16 /var/lost+found
16 /var/lock
12 /var/mail


With these two simple commands you can control the growth of your file system and quickly see if the space is exausted, or if there are problems on inode and which directory is consuming all of your disk.

Why command df and du reports different output ?

Short answer: this is due to open files and how they are counted by the 2 commands.
Long answer: Check this post at nixcraft


failed as Volume Shadow copy operation failed for backup folumes with following error code '2155348129

SkyHi @ Monday, May 02, 2011
We're having the exact same problem with Server 2008 Standard 64-bit. I cannot successfully complete any backups with Windows Server Backup in its default configuration.

Event Viewer also displays error code '2155348129' but our System parition is correctly marked as Active already.

However, If I disable SQL Server VSS Writer in services.msc, the Backup successfully completes. I decided to stop this service when I noticed that its entry in 'vssadmin list writers' was marked as 'non-retryable error'