Server Admin

Website Server Administration

Successful SU For Nobody By Root?

Successful su for nobody by root?

If you are looking through you auth log files you may notice entries saying “session opened for user nobody”. What could this mean and is your server being compromised?

Feb 23 06:25:02 the-cave su[16451]: Successful su for nobody by root
Feb 23 06:25:02 the-cave su[16451]: + ??? root:nobody
Feb 23 06:25:02 the-cave su[16451]: pam_unix(su:session): session opened for user nobody by (uid=0)
Feb 23 06:25:02 the-cave su[16451]: pam_unix(su:session): session closed for user nobody
Feb 23 06:25:02 the-cave su[16453]: Successful su for nobody by root
Feb 23 06:25:02 the-cave su[16453]: + ??? root:nobody
Feb 23 06:25:02 the-cave su[16453]: pam_unix(su:session): session opened for user nobody by (uid=0)
Feb 23 06:25:03 the-cave su[16453]: pam_unix(su:session): session closed for user nobody

Session Opened For User Nobody

Any services that run as a daemon on the server need to be run by a user. Nobody is a system user that is used to run various services. Apache, MySQL, cron and other services will but run as the user nobody.

How Is It Initiated

When one of these services need to run a task, that task will be initiated and the process is then passed to user nobody which then completed the process.

PHP Ping Script Video Tutorial

Webucator, a provider of online and onsite business and technical training, contacted me and asked if they use my php ping script article as a basis for a new training video. The video would be added to their list of PHP courses. I allowed them to use the php ping script as part of their video and a few days later I was sent a link to the newly created php ping script video.

After watching the video Webucator created, I was was truly amazed and it had surpassed all my expectations. Webucator have managed to perfectly convert the written article into an easy to understand, fully comprehensive and simple to follow php tutorial video.

I was impressed with how much detail the above php video tutorial encompassed. The video covers each of the different php ping scripts, and perfectly explains how each of the php ping scripts work. They also highlighted the strengths and usefulness of the each script as well as demonstration a working version of each script.

The video also pays attention to vital parts of each script, such as:

  • Why you should escape arguments passed to the ping script.
  • The situations in which each ping script is most useful.
  • Which ping script you should be using if the website is blocking icmp packets.

Take a look at the video and check out their other training videos. It will be well worth your time.

Grant Privileges To User in MySQL


If you would like to add a user to MySQL and give them permissions to view on or multiple databases, then continue reading. It is a fairly simple process and can be very powerful in keeping your database secure as well as giving people the access to the database they need.

Login To MySQL Server

In order to run these sql commands (sql queries), login to your sql database so we can take a look at the format of the MySQL command.

mysql -u <user> -p

I recommend you don’t enter your password above as people viewing your bash history would see your password. Once you hit enter you will be prompted to enter your password.

Grant Privileges To User in MySQL

Now the format of the grant appears as follows

GRANT <privilege-type> ON <database> TO <user>@`<ip-or-domain>` IDENTIFIED BY '<new-password>'

Here is the breakdown of what each of the variables means.

  • privilege-type: type of privileges to give such as INSERT, DELETE, ALTER, DROP, ALL PRIVILEGES, etc.
  • database: the database/table combination your are giving the user access to (see below for examples).
  • user: username of your choice that the user will use to login to view their databases.
  • ip-or-domain: the location where the user is access the database FROM.
  • new-password: password of your choice that the user will use to login to view their databases.


MySQL GRANT Privileges Examples

Example 1: Gives the user `poweruser` full access to all databases and tables. The *.* means all databases and all tables.

GRANT ALL PRIVILEGES ON *.* TO poweruser@`` IDENTIFIED BY 'some-pass';


Example 2: Create a user with INSERT, DELETE and UPDATE permissions to all tables under the exampledatabase database. They can also only login if they come from the location

GRANT INSERT,DELETE,UPDATE ON exampledatabase.* TO `editoruser`@`` IDENTIFIED BY 'any-pass';


Example 3: Only give delete to a user and they can only access the reports database and the temptable table. The % for their location means they can access it from anywhere and not just a single ip or domain.

GRANT DELETE ON reports.temptable TO `cleanupuser`@`%` IDENTIFIED BY 'their-pass';


Example 4: Gives the root user full access but only from the same location as the database. So anyone outside of the server won’t be able to login. Useful if your website is running on the same server as the database and very secure.

GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` IDENTIFIED BY 'difficult-pass';


MySQL Copy Table From One Database To Another


So you are looking at transferring the data of on MySQL Table into another MySQL Table. Migrating data from database to another database table can be surprisingly easier than you would think.

MySQL Copy Table From One Database To Another

The following query will copy all rows from table_one into table_two. In order for this to work correctly, the number of columns must match. It doesn’t matter if the names of the columns are different, so long as the column count is the same.

INSERT INTO `table_two` SELECT * FROM `table_one`;

MySQL Copy Table With Different Number Of Columns

You can also copy data where the column count is different between the two tables. In order to achieve this, your SELECT will have to return the right number of columns as INSERT statement is expecting.
The exciting part of this is that you can filter which results get transferred by using normal MySQL “SELECT WHERE” syntax as you can see in the below example. In the example, we only transfer the records from table one that are LIKE ‘some value’ and limit the transfer to 20 results.

INSERT INTO `table_two` (`column_A`, `column_B`) SELECT `column_C`, `column_D` FROM `table_one` WHERE `column_name` LIKE '%some value%' LIMIT 20;

Important Note

In the above query, you will notice I select column_C and column_D but I insert it into column_A and column_B. This will work fine even thought the column names don’t match. As long as the column count is the same you will be fine. Assuming that you don’t have foreign key conflict or are missing required columns.

Simple as that.

Logrotate Set File Permissions


If you have ever wondered why your log files randomly change permissions each night. Logrotate could be up to its tricks. Similar to the other article I published on Why is apache randomly restarting which explains why logrotate could be causing apache to restart randomly.

Logrotate Set File Permissions

Each time logrotate runs its course, it will compress, rename and remove older files. Remember that a rename is essentially just a ‘move’ operation. This causes some of your log files to no longer exist (since then have been compressed and renamed). Luckily logrotate will attempt to recreate these files and will set some permissions for it.

Post Rotate

Once the logs are rotated, logrotate will execute any commands set in the post rotate part of the script. For example, my logrotate apache config tells it to restart apache.
It restarts apache so apache can recreates any missing log files. Then the permissions that the newly created log files get are determined by the config file for logrotate.

Example Logrotate Apache Config

/var/www/*/logs/*.log {
        rotate 52
        create 640 root adm
                /etc/init.d/apache2 reload > /dev/null

Choosing The Log Permissions

Edit the logrotate apache file which under Debian is usually found under:

vi /etc/logrotate.d/apache2

Inside this file and most logrotate config files, you will see an entry like this

create 640 root adm

This basically tells logrotate to create any missing files, with the permissions of 640 (640 being the standard unix permisson bits) and root as the user with adm as the group.

Simple as that!

Why is Apache Restarting Randomly


If your apache seems to restart randomly, it can be confusing and difficult to find the issue. I noticed apache on one of my servers was restarting at what seemed like random times.

Why is Apache Restarting Randomly

In my case, Logrotate was to blame and was the cause of the issue. Each time logrotate runs, it will compress, rename and recreate your log file. Furthermore, while rotating your logs it will also remove older logs. Similar to the follow up of this article explaining how to permissions for files that that logrotate creates.

Since the logs files are renamed, it will result in some of your log files to be ‘missing’ since a rename is essentially a ‘move’ operation.

Time To Recreate Apache Log Files

Now that the log files have been renamed, it will recreate the log files. Once the new log files have been created, apache needs to restart so apache can a file pointer to the newly created log files. Logrotate will achieve this by restarting apache, at which point apache will recreate the missing log files.

Example Apache Log Rotate

Here is an example of a logroate apache config. See the section on ‘postrotate’, this is the reason it is restarting apache after each log rotate.

/var/www/*/logs/*.log {
        rotate 52
        create 640 root adm
                /etc/init.d/apache2 reload > /dev/null

Manually Override DNS -Window, Linux and Mac Examples


First off, let me explain what a DNS Entry is in order for us to understand why we would need to override it. Basically a DNS entry is a record or entry that tells us what ip address is of a domain will point to. Such as an example (not actual) IP of could point to a domain such as

Say perhaps we are updating a DNS entry and as the nature of DNS would have it, sometimes it will take up to 48 hours for the DNS to propagate through the Internet. Or perhaps we don’t want to update a DNS record which could affect everyone but rather just change a record for ourselves, locally. In these case, we can manually override the DNS change which will only reflect on our local machine. Below I will show you how to achieve this on Windows, Linux and Mac.

Manually Override DNS on Windows

Open up the hosts file located under “C:\Windows\System32\etc\drivers\“. In there you will see the IP address in the left column and a space separated list of domains to the right. The below example will set the 3 domains of, and to the IP address of

Manually Override DNS on Linux

vi the hosts file which is located under /etc/hosts. Add in a line below the last entry in the same fashion as you would for windows. For example if you wanted to change the ip address for the domain to point to you would enter:

Manually Override DNS DNS on Mac

Mac is the same as the above linux example. Simply edit the hosts file under /etc/hosts and add in the entries as needed. So again, you could enter something such as:

Manually Override DNS Using IPV6

You don’t always have to use a standard IPV4 as the IP address. You can also use IPV6 and enter it into any of the hosts files like so:

fe80::1%lo0 localhost

And that is all there is in Manually Override DNS in windows, linux and mac.

Using Curl As A Wget For Mac Replacement


I was trying to download a file on my Mac and realised that there is no wget for Mac. Since I consistently use wget I decided to find a way to get wget for mac. I found a quick way to create an fake wget command by creating an alias of curl. By creating the alias, I am able to call ‘wget’ and it will invoke curl -O in the background and download the file just as wget would have. This is a quick way to get wget for Mac.

Using Curl As A Wget For Mac Replacement

In order to create an alias of `wget` that will simply run the command curl -O I ran the command below:

echo 'alias wget="curl -O"' >> ~/.bash_profile

Now when i type ‘wget’ it will download the url as you would expect from wget. As mentioned before, in the background it will be invoking curl to download the file. So when I run `wget`, it is actually executing curl -O to download the file as we won’t even notice the difference. Well maybe a small difference. But the end result is the same and your file is downloaded.

Example Using The Replacement wget For Mac


The -O option to curl tells curl to save the URL as a file rather than displaying the source.

And that is all there is to it.

List Of Common Ports And Protocols

List Of Common Ports And Protocols

Below is a list of common ports and protocols as well as the service it is generally associated with. If you feel there are ports that should be on this list, please leave a comment or contact us.

20FTP – data port (File Transfer Protocol)
21FTP – command port (File Transfer Protocol)
22SSH (Secure Shell)
25SMTP – Sending Mail (Simple Mail Transfer Protocol)
43WHOIS – Domain Name Lookup
53DNS (Domain Name System)
67DHCP – Server (Dynamic Host Configuration Protocol)
68DHCP – Client (Dynamic Host Configuration Protocol)
80HTTP – Webservers such as Apache2 and IIS – more info on accessing websites on alternate ports
110POP3 – Receiving emails (Post Office Protocol, version 3)
123NTP (Network Time Protocol)
143IMAP – Receiving emails (Internet Message Access Protocol)
443SSL – Webserver with encryption (Secure Socket Layer)
Plesk Control Panel also uses this port
1433MSSQL – Database (Microsoft SQL Server)
2083cPanel over SSL
2095cPanel Webmail
2096cPanel Webmail over SSL
3128Squid Proxy – Default Squid Proxy Port. Port 8080 is another common port for squid.
3306MySQL – Database
8080HTTP Port (Alternate port generally used when port 80 is already in use – more info)
8443Plesk Control Panel


Accessing a website on a different port

When you access websites, you are, by default, accessing them on the port 80 since this is the default web port used by websites. This means that is the exact same as (where :80 specifies the port number). However if the website server is using another port such as a more commonly used alternate port 8080, then you will need to specify the non-default port in the following format: where is the website domain or IP address and 8080 is the port number the website is running on.

Why Unix Timestamp Is Useful


Unix timestamps are a way or storing a specific date and time. Unix timestamps are a 10 digit number that represents the number of seconds that have passed since midnight Universal Co-ordinated Time (UTC) of January 1st, 1970.

What makes timestamps ever so useful is that since timestamps are recorded as of UTC (or GMT) a single time stamp can be used to to represent all time zones. Once you have your timezone, the unixtime stamp will adjust the time accordingly. For example, a unix timestamp of 1304951846 can represent 10th May at 0:37 AM in London, but it would also represent 10th May at 10:37 AM in Brisbane/Australia.

Why Unix Timestamp Is Useful

How can this be useful? Just think, users can see dates and times on your website relative to their own timezone, rather than the timezone of the server the website is being run on. Being a web developer, I am forever finding myself storing dates do be displayed back to the user. It may be a date a user last logged into a program or website, perhaps even a date that a user posted an article such as this to a website. Once we store a specific timestamp, we can display the time and date to users but also in the correct relevant timezone. On top of which, timestamps are easy to use, and many languages support them.

Online Timestamp Converter

There are online unix timestamp generators to convert to and from unix time stamps such as the one found here.

PHP can convert a timestamp to a human readable format by using the date() function and likewise using strtotime() and mktime() to convert a natural language string to a unixtime stamp to be stored. Short examples are:

PHP Timestamp Example


/* convert unixtime stamp to human time */
echo date('d F Y H:i:a',1304951846); // would display a time of 10 May 2011 00:37:am

/* convert to a unix time stamp */
echo strtotime('+1 Year'); // would return the timestamp of 1 year from today
echo mktime($hour,$min,$sec,$month,$day,$year); // echo a timestamp specified by the variables


MySQL Timestamp Example

MySQL uses the syntax FROM_UNIXTIME to convert data to a human readable format for example:

SELECT *,FROM_UNIXTIME(timestamp_column) FROM `table`;

Free Online Unix Timestamp Converter

Generate your own unix timestamp online using an Online Unix Timestamp generator.