MongoDB “Couldn’t Send Query”

Posted by & filed under Server Admin.

I would get random error messages from my MongoDB based app GoScouter of couldn’t send query It was random and quite frustration. I was not able to find anything definite online about such error, but that it might be a bug in the PHP MongoDB Driver. I was using version 1.2.7, so I did a… Read more »

Qwest DSL and OpenDNS… opting out of the DNS override.

Posted by & filed under Server Admin.

While reconfiguring the network at the church, I noticed that my DNS queries were not getting curbed by OpenDNS. Browsing to ‘bad’ sites should give you a no no page from OpenDNS, but nothing was tripping it… not even 4chan :S

The I realized that Qwest is doing some DNS override where they actually do the DNS query.

The Solution

You need to opt out of this “wonderful” service from Qwest.
http://www.qwest.net/web.help/?confirm=1

After that, it was just fine.

I guess Qwest couldn’t resist trying to pick up that money on the table since they have access to all that traffic…. wonder how much money they make on ads.

Nginx SSL certificate error message “key values mismatch”

Posted by & filed under Server Admin.

When setting up a SSL certificate and chain file for Nginx, you need to combine them into one file. If you combine them in the wrong order you’ll get a message similar to the following.


SSL_CTX_use_PrivateKey_file(" ... /www.nginx.com.key") failed
(SSL: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch)

This means you either didn’t combine them or you combined them in the wrong order. To combine the two together just do something like this.


cat www.example.com.crt www.certificatechain.com.ca > www.example.com.combined.crt

Now you’ll be happy as a lark.

Understanding the Nginx map directive

Posted by & filed under Server Admin.

When switching to Nginx I needed to have a variable that signified if the site was in HTTP or HTTPS mode. So I found this little bit of code.

map $scheme $fastcgi_https { ## Detect when HTTPS is used
default off;
https on;
}

This works great, but I really didn’t understand it until now so let’s take it line by line.

Line 1


map $scheme $fastcgi_https { ## Detect when HTTPS is used

This is where all the glory happens. $scheme is an internal variable within Nginx and is either HTTP or HTTPS (maybe some other ones in the future like SPDY). Then you have $fastcgi_https, this is the name of the variable we’re creating for future use in our config files. Nothing but comments after that stuff.

Line 2 and 3


default off;
https on;

This is our map of values. When Nginx’s $sheme variable is equal to “HTTPS”, then the $fastcgi_https variable will equal “on”, otherwise the variable just equals “off”.

Not too complex, but I just didn’t pick up on the format until now. Read more at
http://wiki.nginx.org/HttpMapModule

The SetEnv equivalent in Nginx for setting environmental variables.

Posted by & filed under Server Admin.

If you need to pass some environment variables to your application from Nginx, you’ll need to specify them in the config file like so.


fastcgi_param APPLICATION_ENV staging;

So for example a more full config for a Zend Framework application


server {
listen 443 default ssl;
listen 80 default;
ssl_certificate /etc/pki/tls/certs/cert.crt;
ssl_certificate_key /etc/pki/tls/private/cert.key;

keepalive_timeout 70;

root /var/www/mysite/public
access_log /var/log/nginx/mysite.access.log main;
index index.php;

location / {
try_files $uri $uri/ /index.php?$args;
}

# set a nice expire for assets
location ~* "^.+\.(jpe?g|gif|css|png|js|ico|pdf|zip|tar|t?gz|mp3|wav|swf)$" {
expires max;
add_header Cache-Control public;
}

location ~* \.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 600;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param APPLICATION_ENV staging;
}

}

There you have it. Go and do likewise.

Error Description: 0 on Nginx with Drupal and Secure Pages

Posted by & filed under Server Admin.

A curious error message popped up after I moved my Drupal sites to Nginx. It would only happen on AJAX type changes, but not all of them. I first noticed it when I went to change the author of a node. Then when I tried to change a View I received this error message.


After checking the logs on Nginx and watching what happens using Firebug’s Net panel, it occurred to me that Drupal was making an HTTP “OPTIONS” request.

The other detail is I was using HTTPS (SSL) enforced with the Secure Pages module. It when I was on the HTTPS side of the site those AJAX requests would be HTTP OPTIONS requests to the non-secure side HTTP.

The Solution

The solution was to disable HTTPS for certain pages in the Secure Pages config settings. Why Drupal was making OPTIONS calls to the none secure side of the site is still a mystery.

BTW. When your on the non-secure side, it makes a regular GET or POST request, not an OPTIONS request.


Nginx + fcgi (fastcgi) + PHP + APC + Zend Framework + CentOS

Posted by & filed under Server Admin.

My newest toy I’ve been playing with is Nginx. Getting PHP to work over FastCGI. The performance gain over Apache + mod_php is quite staggering.

Here are a few things to watch out.

Getting PHP v5.2

Some of my apps are not ready to make the jump to PHP 5.3 just yet, so I needed to get a hold of PHP 5.2. In the past I just install the Zend Server CE it would have all the PHP bells and whistles I could ever need. Not anymore, now it’s time to fend for myself.

Webtatic Repo
http://www.webtatic.com/blog/2009/06/php-530-on-centos-5/
I’ve added webtatic to my repos and followed his advice to disable PHP 5.3 from his repos you add exclude=php*5.3* to your webtatic.repo file.

Now you can install PHP.

APC Opcode Cache

This waa a little more of struggle as I need to install various things to get it to work. I finally ran pecl install apc and it compiled fine. Then I added a file

/etc/php.d/apc.ini

extension=apc.so

PHP will pick that up and just enable it. Make sure to check that it’s enabled by running phpinfo(). Also you can download the source and extract the file apc.php Throw this on your server and run it in the browser, it will give you a nice rundown about the state of APC and let you know if it’s working.

PHP via FastCGI

There are a few ways to accomplish this and much debate on which is the best way, but I followed the instructions on
http://www.cyberciti.biz/faq/rhel-fedora-install-configure-nginx-php5/

It lays it out plain, how to get a FastCGI daemon going. One change I did make though. It has the daemon listening on localhost:9000. I changed my to a socket located at /tmp/phpcgi.socket

Here is the /etc/init.d/php_cgi init script.

#!/bin/sh
#
# php-cgi - php-fastcgi swaping via spawn-fcgi
#
# chkconfig: - 85 15
# description: Run php-cgi as app server
# processname: php-cgi
# config: /etc/sysconfig/phpfastcgi (defaults RH style)
# pidfile: /var/run/php_cgi.pid
# Note: See how to use this script :
# http://www.cyberciti.biz/faq/rhel-fedora-install-configure-nginx-php5/
# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

spawnfcgi="/usr/bin/spawn-fcgi"
php_cgi="/usr/bin/php-cgi"
prog=$(basename $php_cgi)
server_ip=127.0.0.1
server_port=9000
server_user=nginx
server_group=nginx
server_childs=5
pidfile="/var/run/php_cgi.pid"
socket="/tmp/phpcgi.socket"

# do not edit, put changes in /etc/sysconfig/phpfastcgi
[ -f /etc/sysconfig/phpfastcgi ] && . /etc/sysconfig/phpfastcgi

start() {
[ -x $php_cgi ] || exit 1
[ -x $spawnfcgi ] || exit 2
echo -n $"Starting $prog: "
#daemon $spawnfcgi -a ${server_ip} -p ${server_port} -u ${server_user} -g ${server_group} -P ${pidfile} -C ${server_childs} -f ${php_cgi}
daemon $spawnfcgi -s ${socket} -u ${server_user} -g ${server_group} -P ${pidfile} -C ${server_childs} -f ${php_cgi}
retval=$?
echo
return $retval
}

stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} $prog -QUIT
retval=$?
echo
[ -f ${pidfile} ] && /bin/rm -f ${pidfile}
return $retval
}

restart(){
stop
sleep 2
start
}

rh_status(){
status -p ${pidfile} $prog
}

case "$1" in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
rh_status;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 3
esac

Zend Framework

One issue I ran into with Zend Framework, was the location of the sessions folder and the permissions. The default session folder is in /var/lib/php/session this was owned by apache, I just changed the owner:group to nginx:nginx. All was sunshine and roses again.

Installing IonCube on Zend Server CE

Posted by & filed under Server Admin.

ionCube

http://www.ioncube.com/
For better or worse, ionCube is an encryption method for those that want to protect their code. A pain the neck for system admins, but some want to protect their PHP code, whatever.

Problem… Zend Optimizer +

Zend Optimizer+ does not play well with ionCube for whatever reason, so it’s really picky on what order they get loaded during startup. It’s important to put the configurations in the correct order, or it will just error out during start up.

Installing ionCube

You’ll want to grab the loader files from here
http://www.ioncube.com/loaders.php

I downloaded and unzipped them to

/usr/local/ioncube

Edit php.ini file

Since ionCube is a Zend Extension and not a Zend Module (what’s the difference? I couldn’t tell you, but there is a different) we need to open up the file

/usr/local/zend/etc/php.ini

and at the very bottom it should look something like this.

; Local Variables:
; tab-width: 4
; End:
[Zend]
zend_extension=/usr/local/ioncube/ioncube_loader_lin_5.2.so
zend.install_dir=/usr/local/zend
zend.conf_dir=/usr/local/zend/etc
zend.ini_scandir=conf.d

Of course the important line is the ioncube line, it’s important that it appears before the other lines.

Big Note about versions

It wasn’t immediately obvious to me, but you need to match your PHP version with the version of ionCube (You can tell I’m using PHP version 5.2).

Verify install

After it’s done you can restart the web server (if the web server doesn’t start check your log files for clues). Then go to the Zend admin panel to see the PHP INFO page. You should see a section that looks like this….

php-info-ioncube.png

BD… BD.. BD.. That’s all folks

porky-pig.jpg

Rollback CentOS updates with RPM and YUM

Posted by & filed under Server Admin.

Every server administrator likes to sleep at night and every server admin knows server updates could prove disastrous. Just found out that RPM and Yum allow you the ability to rollback an update if some how it sent your system into a choking fit.

In your /etc/yum.conf add this in there somewhere

tsflags=repackage

This will repackage all your old files from the package (including config files) and store them in /var/spool/repackage

Also add the file /etc/rpm/macros and place this in that new file

%_repackage_all_erasures 1

When things go wrong

If you want to rollback changes to a certain time, then just issue commands like


rpm -Uhv --rollback '9:00 am'
rpm -Uhv --rollback '4 hours ago'
rpm -Uhv --rollback 'december 25'

Untested Yet

This is just stuff I’m reading, I have yet to test this under fire, maybe I’ll play around on a test server

Resources

http://dailypackage.fedorabook.com/index.php?/archives/17-Wednesday-Why-Repackaging-and-Rollbacks.html

Web Server Setup of Permissions and Folders for multiple developers

Posted by & filed under Server Admin.

This summarizes how I currently set up my servers so that I can have multiple developers accessing certain client files, but retain control on which clients. The key to this whole process is groups.

Users

Create user accounts for your developers.

# useradd developer1
# passwd developer1
# useradd developer2
# passwd developer2

Groups

Create groups that section off your clients. For example.

# groupadd client1
# groupadd client2

Add apache to your groups

The web server is going to need access to the files so we will add apache to any groups we create for this purpose.

# usermod -a -G client1 apache
# usermod -a -G client2 apache

This will add apache to the groups client1 and client2.

Add developers to your groups

Your developers need to access your client files as well so we assign them to the groups. This will assign developer1 -> client1 and developer2 -> client2. Fun stuff.

# usermod -a -G client1 developer1
# usermod -a -G client2 developer2

Note: the “-a” appends, if you don’t have this option, then it overwrites the users groups list, not good.

You could also section off your groups in other ways, such as by website.

DocumentRoot Folders

The web server folders will be located at /var/www/. So you will have :


/var/www/client1
/var/www/client2

Setting the setgid bit


# chmod 2770 /var/www/client1
# chmod 2770 /var/www/client1

Assigning User and Group ownership to the directories

This will have to be done by root, because you cannot assign ownership to another person unless you are root. Also, I created a dummy user of “www” to be the user owning the files, it doesn’t matter who owns the files because we are not relying on that part of the permissions.

# chown www:client1 /var/www/client1
# chown www:client2 /var/www/client2

The permissions on these folders will now look like

#ls -l /var/www/
drwxrws--- 6 www client1 4.0K Apr 14 15:28 client1
drwxrws--- 6 www client2 4.0K Apr 14 15:28 client2

This will ensure that all files and folders created below this directory

Result

Developer1 can access Client1′s files, change them, create new folders/files, but cannot get to Client2′s files. Developer2 has the visa-vers result.

NOTE: any new file created by the developers will be owned by the developer and the group (e.g. the ownership will be developer1:client1). This is not a problem since we are not really checking user level permissions.

Helpful commands

Set the setgid on all folders.


# find ./* -type d -print0 | xargs -0 chmod 2775

Set all files to appropriate permissions


# find ./* -type f -print0 | xargs -0 chmod g+rw