Linux
To run a bash script without executing it, do bash -n scriptname.sh
To see help commands do command --help or man command. To paste into PuTTY, use SHIFT + INSERT.
For detailed software and hardware info do apt-get install hardinfo then hardinfo. For CentOS 6 use this.
To write to a user in the same SSH server, do w, get their tty session and then do write user ttySession. If they are root, do write root Session
Awk introduction, If manual.
Append date to same line
Either of these will work:
| awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }' | ts '%F %T'
To customise date, put a + symbol in front of the flag:
date +%R 14:32
To get this format of the date/time:
24 May 2013 10:25:33
Use:
date +%d\ %B\ %Y\ %H:%M:%S
authorized_keys (RSA)
This will show you how to SCP, SSH and rSync without prompting for password between two servers.
Whenever you need to use SCP to copy files, it asks for passwords. Same with rSync as it (by default) uses SSH as well. Usually SCP and rSync commands are used to transfer or backup files between known hosts or by the same user on both the hosts. It can get really annoying the password is asked every time. I even had the idea of writing an expect script to provide the password. Of course, I didn't. Instead I browsed for a solution and found it after quite some time. There are already a couple of links out there which talk about it. I am adding to it...
Lets say you want to copy between two hosts host_src and host_dest. host_src is the host where you would run the SCP, SSH or rSync command, irrespective of the direction of the file copy!
On host_src, run this command as the user that runs SCP/SSH/rSync
ssh-keygen -t rsa
This will prompt for a passphrase. Just press the enter key. It'll then generate an identification (private key) and a public key. Do not ever share the private key with anyone! ssh-keygen shows where it saved the public key. This is by default ~/.ssh/id_rsa.pub:
Your public key has been saved in <your_home_dir>/.ssh/id_rsa.pub
Transfer the id_rsa.pub file to host_dest by either FTP, SCP, rSync or any other method.
On host_dest, login as the remote user which you plan to use when you run SCP, SSH or rSync on host_src.
Make sure the folder ~/.ssh exists first, if not do:
mkdir ~/.ssh
Copy the contents of id_rsa.pub to ~/.ssh/authorized_keys
cat id_rsa.pub >>~/.ssh/authorized_keys chmod 700 ~/.ssh/authorized_keys
If this file does not exists, then the above command will create it. Make sure you remove permission for others to read this file. If its a public key, why prevent others from reading this file? Probably, the owner of the key has distributed it to a few trusted users and has not placed any additional security measures to check if its really a trusted user.
Note that SSH by default does not allow root to log in. This has to be explicitly enabled on host_dest. This can be done by editing /etc/ssh/sshd_config and changing the option of PermitRootLogin from no to yes. Don't forget to restart SSHD so that it reads the modified config file. Do this only if you want to use the root login.
Well, thats it. Now you can run SCP, SSH and rSync on host_src connecting to host_dest and it won't prompt for the password. Note that this will still prompt for the password if you are running the commands on host_dest connecting to host_src. You can reverse the steps above (generate the public key on host_dest and copy it to host_src) and you have a two way setup ready!
.bashrc
vim /root/.bashrc
Colours
https://wiki.archlinux.org/index.php/Color_Bash_Prompt
Add these:
alias ls='ls --color=auto' alias grep='grep --color=auto'
source /root/.bashrc
vim /root/.vimrc
syntax on
Exit your session and re-enter it.
Crontab editor
Add this line in:
EDITOR=vim; export EDITOR
crontab -e
Binary/binaries
These are normally in the bin or sbin folder for a program.
Calendar
apt-get install gcal gcal -K -q GB_EN December/2012-January/2013 # Holidays for Dec/2012 and Jan/2013 with week numbers
Credit to User MPB
Check Linux version/kernel
For Ubuntu do cat /etc/issue or for some CentOS distributions use cat /etc/redhat-release
uname -a uname -r #for just the kernel uname -rs #for OS and kernel
Check if SELinux is enabled
apt-get install chkconfig yum install chkconfig chkconfig --list cat /etc/sysconfig/selinux sestatus selinuxenabled
Check if Virtualization is available for server
CentOS:
egrep '(vmx|svm)' --color=always /proc/cpuinfo
Ubuntu:
apt-get install cpu-checker kvm-ok
Check your PuTTY (TTY) session
Type this into command line:
tty
CLI/bash Commands and scripting
- For variables with multiple pipes "|", use tacs `` instead of quotes ""
- If you are attempting to use the Unix mail function, you have to specify a body otherwise it will hang.
- If you have an if statement and its requirements are not met (e.g. greater than) and it then moves onto the next if statement, if it uses a mail function it may send it to the root user's email or the Admin/Administrator's email address. To avoid this use > /dev/null . 2>&1 likely won't work.
- It seems if you are using the read function, you can only call a variable that is inside of it (subshell), from here.
- To stop a ping after x amount of responses, do ping -c x or use ping -oc y (where y equals a maximum amount of tries)
- Use >> to append an output to the end of the file.
- The use of && means that you only echo the name of the directory if the directory creation is successful.
- The $() syntax allows you to load anything echoed to STDOUT to be loaded into a variable, and the single quotes ensure that if there are any spaces in the directory name, it still gets loaded into a single variable. To use command substitution, enclose any command that generates output to standard output inside parentheses and precede the opening parenthesis with a dollar sign, $(command). Command substitution is useful when assigning a value to a variable. It is handy for using the output of one command as an argument to another command. Why is $(...) preferred over `...` (backticks)? . A good use of this is in http://serverkb.co.uk/tools/slow.sh
- To quote double quotes (") do the following: echo -e "Testing \"quotes\" here" - this will show as Testing "quotes"
- Quotes prevent wildcard (*) expansion.
$?
This is the exit status/code of the last executed function/program/command.
ack
To look into.
Awk
To print out a list of just folders/files you want, do;
ls -l filepath | awk '{print $9;}'
This won't work correctly if there is spaces in the filename. To resolve this, use this command whilst in the directory itself.
To do multiple sections of a result, do:
awk '{print $1,$2,$4,$X;}'
If you want to get rid of/cut certain/specific lines/rows from STDOUT aka print a specific line, use awk in this way:
awk 'NR==22'
This is for use without a file. This example will only display the 22nd row from your output.
Notes: Blank lines count as a row. To do multiple lines do awk 'NR==22,NR==25' . This will output line 22-25.
The command sed '22 ! d' would do the same as the awk 'NR==22' example.
To get rid of pipe symbols in a file, do:
awk -F'|' '{print $1,$10}' FileWithPipes > FileWithoutPipes
Alternatively if you get a list, e.g of domains from MySQL with only one column selected, put them in a file and you can remove the pipes by doing:
cat domainlist | awk '{print $2}' > list
awk '{ printf "%-20s %-40s\n", $1, $2}' allows you to print information in columns
Cut
This tool can be used in an example where you get an output but want to strip it to exactly what you need e.g.
lookupipscript.sh <IPaddress>
Output below:
Plan : Bronze, Silver, Gold Type : IPv4 or IPv6 URL : http IP : 0.0.0.0(primary)
lookupipscript.sh <IPaddress> | sed 'row ! d' | awk '{print $column;}'
This would output 0.0.0.0(primary). To get just the IP address and not the "(primary)" section, do:
| cut -c 1-7
Cut counts the first number/letter as 1, not 0.
eval
Use this of you want run a variable after a pipe and to shorten down your scripts. e.g. in http://serverkb.co.uk/tools/getdns.sh
ns="ns.nameserver.co.uk" d="domain.co.uk" g="grep $d | grep -v 'DiG\|;'" echo "dig @$ns $d A" dig @$ns $d A | eval $g
It is a good replacement instead of $() or `` or running just a variable.
Find
Exclude directories
Guide Part 1
Find Help (this includes mtime commands)
find . -maxdepth 1 -type f -printf "%f\n" | sed s/,$//
Finds all files that contain "some string". This command is useful in a directory (e.g. mail), so you would do ls -lah | grep year-mm then:
find . -type f -exec grep -l "some string" {} \;
for loop examples
Functions
A prime use of functions is in our script to replace the date.timezone settings in php.ini at http://serverkb.co.uk/tools/phptimezone.sh
#!/bin/bash APACHEPHP="/etc/php5/apache2/php.ini" CURRENT="\n\nThis is the current timezone configuration:" DONE="If the settings were wrong, they are as below now:" ETC="/etc/php.ini" function UBDEB(){ echo -e "\nThe operating system is Debian/Ubuntu, so editing $APACHEPHP" $CURRENT grep "date." $1 | head -7 | grep -v '; http\|Define' ; echo "" sed -i -e 's/;date.timezone\ =/date.timezone\ =\ \"Europe\/London\"/g' $1 sed -i -e 's/;date.default_latitude\ =\ 31.7667/date.default_latitude\ =\ 51.500181/g' $1 sed -i -e 's/;date.default_longitude\ =\ 35.2333/date.default_longitude\ =\ 0.12619/g' $1 echo $DONE grep "date." $1 | head -7 | grep -v '; http\|Define' ; echo "" } function RHEL(){ echo -e "\nThe operating system is likely CentOS, editing $ETC" "$CURRENT grep "date." $1 | head -7 | grep -v '; http\|Define' ; echo "" sed -i -e 's/;date.timezone\ =/date.timezone\ =\ \"Europe\/London\"/g' $1 sed -i -e 's/;date.default_latitude\ =\ 31.7667/date.default_latitude\ =\ 51.500181/g' $1 sed -i -e 's/;date.default_longitude\ =\ 35.2333/date.default_longitude\ =\ 0.12619/g' $1 echo $DONE grep "date." $1 | head -7 | grep -v '; http\|Define' ; echo "" } if [[ `cat /etc/issue | sed '1 ! d' | awk '{print $1;}'` == "Debian" || `cat /etc/issue | sed '1 ! d' | awk '{print $1;}'` == "Ubuntu" ]]; then UBDEB "$APACHEPHP" else RHEL "$ETC" fi
Credit to Sam Teale for helping me with this.
Grep
Exclude multiple directories
grep 'string' -R . -il --exclude="/proc" --color grep -iR "string" * | grep -v "/proc"
Look for IP address
do this:
grep -E -o '(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]?)'
courtesy of SO
Note to self:
d 0000 | grep IP | awk '{print $4}' | grep -E -o '(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]?)'
Multiple terms
Exclude using -v
grep 'chroot\|default\|fs\|fs-passwd\|httpsdocs'
It is important to remember to not put a \| after the last text term.
Remove pipe symbols from MySQL
mysql -pPASSWORD admin -e"select domain from domains;" grep -v "|" > FileWithoutPipes
Switches/flags
-A after -B before
Head
If for example you do /var/qmail/bin/qmail-qstat and it prints two separate lines, do this to get just the first line:
head -1
If and Else
Use -f for files, -d for directories
if [ -f $VARIABLE ] then parameters (e.g. echo, mkdir, touch, rm) fi
Combine if and $? to get to do something with the exit status of the last executed command.
if [ $? -eq 0 ]; then commands fi
If you want to prompt for both y and Y for yes input, use:
if [[ $variable1 = y || $variable2 = Y ]];
Another example of the above if x or y is here. Use || to do if = x or y.
if [[ value = x || y ]
If you get the following error when executing a bash script outside of it's directory:
[[: not found
You need to either bash /file/path/to/script or alter the syntax to use:
-eq instead of =
or
(( command )) instead of [[ command ]]
If value equals multiple values
Using the syntax above:
echo -ne "Enter a server number (1, 2 or 3): " read ServerNo if [[ ( $ServerNo -eq 1 ) || ( $ServerNo -eq 2 ) || ( $ServerNo -eq 3 ) ]]; then echo "$ServerNo is a valid server, continuing." else echo "$ServerNo is not a valid server, exiting." fi
read
One of the simplest uses of this command is to do it like so:
echo -ne "Enter the filename you want to create: " read createdfilename touch $createdfilename
sed
If you want to get rid of/cut certain/specific lines/rows from STDOUT aka print a specific line, use sed in this way:
sed '22 ! d'
This is for use without a file. This example will only display the 22nd row from your output.
Notes: Blank lines count as a row. The command awk 'NR==22' would do the same.
To print individual/separate lines, e.g. 1, 4 and 5:
sed -ne '1p;4p;5p'
To print between lines 22 to 39:
sed '22,39 ! d'
To put a variable inside sed, use quotes instead of apostrophes:
sed "22,$variable ! d"
To delete parenthesis/brackets, use this:
sed 's/[()]//g'
sed 's/[)]//g'
sed 's/[(]//g'
sed 's/[[]]//g'
sed 's/[]]//g'
sed 's/[[]//g'
Replace text in a file
sed -i -e 's/TextToFindToReplace/TextToReplaceItWith/g' filename
To handle spaces, forward slashes and quotes " ", use back slashes like you do in filenames:
sed -i -e 's/File\"quotes\"WithA\ Space/HereIs\/ABackslash/g' filename
sleep and usleep
Use sleep if you want to "wait" X seconds. usleep is measured in microseconds and cannot do more than 1 second. 100000 (100,000 / 100k) = 0.1 seconds. 1,000,000 = 1 second.
Shells and subshells
If you want a script to make changes to your current shell, not the subshell a bash script works in, execute the script by doing the following (sometimes you may need to do ./ still):
. script
This information was provided by these sources: 1, 2
tee
Tee command is used to store and view (both at the same time) the output of any other command.
Tee command writes to the STDOUT, and to a file at a time.
By default the tee command overwrites the file. You can instruct tee command to append (like >> does) to the file using the option –a as shown below.
ls | tee –a outputfile
Use [[ instead of [
Variables
If you store a variable with a command within it as follows:
variablename=`command`
you should instead store it like this:
variablename=$(command)
And then call it as follows:
${variablename}
xargs
This can be incredibly useful if you get "Argument list too long"
cd /to/directory , find . -type f | xargs rm -Rf
If you need to remove a list of files with spaces in them, do this:
ls -lah | grep "SpecificString" | awk '{print $9,$10,$11,$etc}' | xargs -I {} rm -v {}
Use ls -lh to not include hidden files/file starting with a full stop.
For simple removal of normal files do this in a screen session:
ls -lh | awk '{print $9}' | xargs -t rm
Compare a remote file with a local file
ssh user@host cat /path/to/remotefile | diff /path/to/localfile -
Credit to User Root
Compare files in a directory
diff -bur folder1/ folder2/
Warning: when doing diff on folders, if the timestamps are different it will think the files are different. If you actually compare the files, they will be the same.
Console Clock in corner
while true; do echo -ne "\e[s\e[0;$((COLUMNS-27))H$(date)\e[u"; sleep 1; done &
Warning, this auto scrolls your SSH session. To kill it, do:
ps aux | grep bash | grep -v grep
Then kill the bash session at the time you ran it:
kill <processid>
Credit to User Squiidux
-->
Cronjob/Crontab
To check a cronjob has at least attempted to run/execute, check this at the time of execution:
tail -f /var/log/syslog | grep CRON
crontab -e crontab -l * * * * * command to be executed - - - - - | | | | | | | | | +----- day of week (0 - 6) (Sunday = 0 or 7) | | | +------- month (1 - 12) | | +--------- day of month (1 - 31) | +----------- hour (0 - 23) +------------- min (0 - 59)
Guides:
http://www.adminschoice.com/crontab-quick-reference
To do a job every X minutes, do */X * * * *
To do a job every minute in a specific hour, do * X * * *
To do a job every X hours, do * */X * * *
To do a job every day at X hour on the hour, do 0 9 * * * for 9am each day.
To do a job every week at 2am on Sunday, do 0 2 * * 0
To monitor active cron jobs, do tail -f /var/log/cron
/usr/local/bin/php: No such file or directory
Do whereis php
Generally it is actually in /usr/bin/php
Cron Daemon email
If you get the below email:
cd / && run-parts --report /etc/cron.daily /etc/cron.daily/sysklogd: chown: cannot access `/var/log/mail.warn': No such file or directory chown: cannot access `/var/log/syslog': No such file or directory chown: cannot access `/var/log/mail.info': No such file or directory
Do the following:
cd /var/log touch /var/log/mail.warn /var/log/syslog /var/log/mail.info /etc/init.d/sysklogd restart
Date
Spaces
To put spaces between variables (e.g +%H%M) use single quotes:
The time is `date '+%R:%S %Y %Z'` on the following Day/Month/Year `date '+%a %b %d'`
Echo colours
Tips for colours and formatting
Place 0; for the normal version (e.g. Black is 0;30)
Place 1; before these to get the light colour version.
Here are the colour codes:
Colour | Foreground | Background |
Black | 30 | 40 |
Dark Grey | 1;30 | 1;40 |
Red | 31 | 41 |
Light Red | 1;31 | 1;41 |
Green | 32 | 42 |
Light Green | 1;32 | 1;42 |
Yellow | 1;33 | 1;43 |
Brown | 0;33 | 0;43 |
Blue | 34 | 44 |
Light Blue | 1;34 | 1;44 |
Magenta (Purple) | 35 | 45 |
Light Purple | 1;35 | 1;45 |
Cyan | 36 | 46 |
Light Cyan | 1;36 | 1;46 |
White | 37 | 47 |
Light Gray | 0;37 | 0;47 |
An example:
#!/bin/bash wipe="\033[1m\033[0m" black="40m" darkggrey='\E[1;30m' red='\E[31m' lightred='\E[1;31m' green='\E[32m' lightgreen='\E[1;32m' yellow='\E[1;33m' brown='\E[0;33m' blue='\E[34m' lightblue='\E[1;34m' purple='\E[35m' lightpurple='\E[1;35m' cyan='\E[36m' lightcyan='\E[1;36m' white='\E[37m' lightgray='\E[0;37m' green='\E[32m;'
echo -e "$green$black" echo Hello World echo -e "$wipe"
or
echo -e "Output a ${green}coloured${wipe} word."
./colourtest.sh Hello World
The Hello World text appears green.
Execute one off command whenever
echo "ls -l" | at midnight
This is an alternative to cron which allows a one-off task to be scheduled for a certain time.
Credit to User Root
File Locations (index priority)
/etc/apache2/mods-enabled/dir.conf (on Ubuntu) or /etc/httpd/conf/httpd.conf (on CentOS, ~line 402) and it should show something like:
DirectoryIndex index.html index.html.var index.shtml index.cfm index.php index.htm
This shows the default priority in which the index page is picked up and this can be set in the .htaccess file as well with:
DirectoryIndex index.html index.php
These are good places to check if you are using all of your disk space.
cd /var/log
cd /var/www/vhosts (website and statistics)
cd /var/lib/mysql (database) or mysql/mysql
cd /usr/bin/mysqldump (mysql dump)
cd var/qmail (mail logs, queue and configuration)
cd /var/lib/psa/dumps (physical Plesk backups)
cd opt/psa/tmp/ (Plesk stores temporary files here for backups)
File Permissions
One of the best permissions guide
The values and their equivalent permissions. R is Read, W is Write and X is Execute. There are three sets on a file or folder (e.g. -rwx-w--w- , -rw-r--r-- , -rwxr-xrwx) so you need to put in a value of three (or four in rare occasions) for a file/folder e.g. 644.
0 ---<br> 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx
The syntax for chmod is (for example) 755 fileorfolder. The -R option can also be used to set the permissions on anything below a folder.
The syntax for chown is chown user:group fileorfolder . To apply the user:group to anything below a folder you need to use the -R option.
Permissions Calculator
Help Guide 1
Help Guide 2
Unix Notation
File protection with chmod
If you use PHP Support as Apache module, it will use the third value of -rw- r-- r-x to permissions. If it is using Fast CGI it will use the user:group for the first two values -rwx rw- --x
If you are using Plesk a good place to check if you are getting Forbidden errors on your website is /var/www/vhosts/yourdomain.com/httpdocs/statistics/logs/error_log . Access your site and tail -f that file. If you get .htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable name your .htaccess file correctly, set your httpdocs to 757 and see this link.
Special permissions
There is also a, g & s which are not widely used as it just needs additional representation at the special/setid permission to the group.
To set a file to -rws--x--x for example use
4 = setuid - s 2 = setgid - s 4 + 2 = S 1 = Sticky Bit 4 + 2 + 1 = T 2511 -r-x--s--x (e.g. /var/qmail/bin/qmail-remote or /var/qmail/bin/qmail-queue) 4655 -rwSr-xr-x 4711 -rws--x--x 4744 -rwsr--r-- 4755 -rwsr-xr-x 6411 -r-S--s--x. 6511 -r-s--s--x 6644 -rwSr-Sr-- 6666 -rwSrwSrw- 7000 ---S--S--T 7644 -rwSr-Sr-T 7711 -rws--s--t 7744 -rwsr-Sr-T 7755 -rwsr-sr-t
Owner and Group advice for websites
Find command guide
FreeBSD
- mysqldump location: /mysql/bin/mysqldump
- Remove syntax:
- rm -r folderName
- Generic tunneling interface starts with gif
Check software versions
fetch instead of wget
To download a file.
whereis instead of locate command
To find files/folders.
Full Directory listing
apt-get install tree yum install tree tree > tree.txt
If you feel adventurous do cat tree.txt , it will take a while ;)
Find the deepest directory in your server/file structure
find . -type d -printf '%d:%p\n' | sort -n | tail -1
Find and remove specific file types from current directory
cd into the directory find . -type f -name '*.filetype' -exec rm -v {} \;
Line count a file
wc -l /file/path
Generate random number
Between 1 and 10:
seq 10| shuf | head -1
GeoIP - Block countries accessing website
Ubuntu: apt-cache search geoip ; apt-get install geoip-database libgeoip-dev libgeoip1 python-geoip geoip-bin libapache2-mod-geoip tclgeoip
CentOS: yum list |grep -i geo , yum install GeoIP.x86_64
http://www.webhostingtalk.com/showthread.php?t=959646
http://askmatt.co.uk/blog/2010/05/block-countries-using-apache-mod-geo-ip-list-of-countries-by-fraud-risk
Gunzip and Zip
To gzip a file (.gz) up, do:
gzip file
The above won't work for folders.
Or if zip is installed:
zip -r filename.zip filename
To unzip a .gz file, do:
gunzip file
Hostname guide (rough)
If the server runs Plesk and Virtuozzo, the permanent one needs setting on the hardware or in Virtuozzo.
Run dig -x IP.IP.IP.IP from any Linux server and it will show you the PTR/hostname.
Note: Most servers by default come with a non resolving hostname of localhost, localhost.localdomain or something generic.
The hostname should never be left as the default value on a server sending mail, as it is one of three things mail recipient's mailservers see to determine if mail is spam or not. The other two are reverse DNS and the SMTP banner.
If Plesk throws an error when clicking Websites & Domains tab regarding hostname -f, see this resolution.
.htaccess
inode usage
df --si df -ih
A lot of the time the cause can be /tmp (/var/lib/php/session/ on Plesk) due to sessions. You may want to delete the files in there.
Investigating high load
If you are getting a high load average in top, these are some of the steps you can take to investigate the issue.
Check which process has the most open of itself:
ps aux | awk '{print $11}' | sort | uniq -c | sort -nk1 | tail -n5
Stop that process, then run the above command a second time. Then start it again and run the command a third time.
Useful software
- top
- htop
- iotop
All these will do the job. Firstly check the CPU wait time, this is shown within top in Cpu(s): 8.0%us, 2.8%sy, 0.0%ni, 40.7%id, 48.3%wa
%wa in
If this is high, check the Status column (S column in top) to see if any are labelled D. The processes blocked on IO are the ones marked as D.
On a Plesk server
Ensure sites are running PHP as Fast CGI Application instead of Apache module so you can see which USER the process is running as. Pressing the letter "c" on your keyboard will show the path and normally the website name.
wget http://serverkb.co.uk/tools/memcpu.sh ; chmod +x memcpu.sh ; ./memcpu.sh > usage.log & tail -f usage.log
You can alter the PHP Handler on Plesk boxes in the psa database easily by doing:
mysql -uadmin -p`cat /etc/psa/.psa.shadow`; use psa select * from hosting\G select dom_id,www_root,php_handler_type from hosting; update hosting set php_handler_type="module" where dom_id=x;
If sites run PHP as an Apache module scripts will execute as the Apache user www-data, this can make it difficult to see which site they belong to. This also means scripts run with privileges of the Apache user so if an account is compromised an attacker can get access to all other accounts. Also running as Apache module can make the Apache process CPU report look artificially high. Running PHP as Fast-CGI executes scripts as an FTP user associated with each subscription allowing easier identification of problem scripts and limit the damage of rogue scripts.
CPU reports are not an easy way to determine server health. We'd recommend you look at changes and trends rather than the absolute numbers. Most importantly consider your real world performance.
Linux Container
This install below is for an Ubuntu physical server, I may update this in the future for CentOS, Fedora and others.
https://help.ubuntu.com/12.04/serverguide/lxc.html
If you need to get file off the container, you can just scp it off. If the recipient server is slow, try moving the file to the host machine by doing:
scp -Psshport file root@hostIPaddress:~
Installation of LXC
apt-get install lxc cat /etc/init/lxc-net.conf | grep USE_LXC_BRIDGE
If true set to false unless you want the containers to NAT to your servers real IP addresses, and to be accessible externally.
Pre-container creation steps
To reduce errors pre-container creation do the following:
dpkg-reconfigure locales locale-gen en_GB update-locale LANG=en_GB.UTF-8
Creating/deleting containers
Check the templates below and pick one:
cd /usr/lib/lxc/templates/ ; ls -lah
Create a container from one of the templates:
lxc-create -t ubuntu -n NameOfTheContainer
If you want to install the fedora package, do apt-get install yum
To delete it just do:
lxc-destroy -n NameOfTheContainer
Start/stop a container
lxc-start -n NameOfTheContainer -d
/etc/init.d/lxc stop
Access the container
The default user is 'ubuntu' with the password 'ubuntu', to enter a container, do:
lxc-console -n NameOfTheContainer sudo -i
Exit using Ctrl + a, then press q
To re-enter the container, do lxc-console -n NameOfTheContainer and then press enter (you may have to a few times)
Access externally:
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 10.0.3.61:22
Make sure you remove this rule afterwards and DO NOT reboot your server.
Configuration settings
- By default you can ping a container from the host, and vice versa, and you can ping the outside world from the container.
- You can set the hostname just like a normal server, if you want to rename the container.
Default configuration of system files
cd /var/lib/lxc/nameofcontainer/rootfs/etc/sysconfig/network-scripts vim ifcfg-eth0
DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes HOSTNAME=phptester NM_CONTROLLED=no TYPE=Ethernet MTU=
vim /var/lib/lxc/nameofcontainer/config
lxc.network.type=veth lxc.network.link=lxcbr0 lxc.network.flags=up lxc.network.hwaddr = MAC Address lxc.utsname = MT
vim /etc/lxc/lxc.conf
lxc.network.type=veth lxc.network.link=lxcbr0 lxc.network.flags=up
You can add the below to /etc/network/interfaces
auto br1 iface br1 inet dhcp bridge_ports eth0
Fedora
The mirrors/repositories the container uses may be broken by default, don't try to install anything. You'll likely get:
Error: Cannot retrieve repository metadata (repomd.xml) for repository: fedora. Please verify its path and try again
And you likely won't be able to ping anything except the host machine and localhost/127.0.0.1
iptables -t nat -A POSTROUTING -s ContainerIP/24 -j SNAT --to-source PhysicalHostIP
iptables -t nat -A PREROUTING -m tcp -p tcp --dport 10022 -j DNAT -i eth0 --to-destination ContainerIP:80
iptables -t nat -A PREROUTING -m tcp -p tcp --dport 10443 -j DNAT -i eth0 --to-destination ContainerIP:443
vi /etc/yum.repos.d/fedora.repo vi /etc/yum.repos.d/fedora-updates.repo
Uncomment (#) the lines starting with "baseurl"
yum update
OpenSUSE
http://www.lacerta.be/d7/content/opensuse-lxc-container-inside-ubuntu
List containers
lxc-list
Set passwords
Log in as the root user of the container:
Fedora container:
Username: root Password: root
Set the root password to something different:
passwd
You will need to do yum install vim when inside the server.
Ubuntu container:
sudo -i Username: ubuntu Password: ubuntu
Set the user's password:
passwd ubuntu
Set the root user's password:
passwd
SSH in externally
To route from externally through the host to the container, just do the below iptables rule:
iptables -t nat -A PREROUTING -p tcp --dport 1337 -j DNAT --to 10.0.4.60:22 iptables-save
In the above case we are saying:
- You want to SSH in on port 1337
- The container's eth0 IP address is 10.0.4.60
- Then below we are saying the physical machine has an IP address of 110.111.112.113
Then externally from the server do:
ssh [email protected] -p2222
And bingo! You should be in the container.
passwd
LSB Init Scripts
ls list only directories or files
Directories:
ls -lad */
Files:
ls -la | grep -v ^d
Kill tty session
w ps aux | grep bash | grep -v grep ps aux | grep tty | grep -v grep kill -HUP <processid>
Maldet
Documentation
Maldet .tar.gz
Install and Configure
cd /root ; wget http://serverkb.co.uk/tools/maldet.sh ; chmod +x maldet.sh ; ./maldet.sh
Always run your scans from chroot environment (if it has one/is possible) and in Screen (screen -S NameIt), and detach by doing CTRL + A, then press D
Scan reports are normally stored in /usr/local/maldetect/sess/ as session. files.
maldet -a -e -l filepath
Manually alter time/date
Ubuntu
date date mmddtimeyear #as seen below
Cent OS
cd /etc/ ls -lah rm localtime ln -s /usr/share/zoneinfo/Europe/London /etc/localtime date mmddtimeyear | | | | ---> 2012 | | | 24hr --> XX:XX without : | | dd -------> day | mm ---------> month /etc/init.d/ntpd restart or start date
PID
Under construction.
Process ID.
To determine the usage of a specific process, do top -p PID
The maximum number of pids can be obtained from /proc/sys/kernel/pid_max
.profile
Put this in .profile file for on user startup:
echo "" ; df -h | sed -ne '1p;5p' ; echo "rootfs" echo "" ; free -m echo "" ; w | head -1 | sed 's/^ *//g' echo "" ; w | tail -10 | grep -v average ; echo ""
Proxmox
To access via the web go to https://IPaddress:8006
Rough notes:
apt-get install sudo
Proxmox
/var/lib/vz
dump is for backups
images is for OS images
private is for OpenVZ container file systems
template/cache is for OpenVZ templates
http://openvz.org/Download/template/precreated
Create VM creates KVM
Create CT creates OpenVZ container
vzctl enter id
vzctl start/stop id
iptables -t nat -A POSTROUTING -o vmbr1 -j MASQUERADE
restart networking on host and CT
cman_tool: Cannot open connection to cman
pvecm status pvecm nodes cman_tool: Cannot open connection to cman, is it running ?
service pve-cluster restart pvecm delnode NodeName
Force remove an OpenVZ container
vzctl stop 100 ; vzctl destroy ContainerID cd /var/lib/vz/private rm ContainerIDfolder -R cd /var/lib/vz/root rm ContainerIDfolder -R cd /etc/pve/nodes/ContainerName/openvz mv ContainerID.conf ContainerID.bak
Make sure it does not exist in cat /etc/pve/.members
Remount a logical partition/volume
lvdisplay
/dev/mapper/pve-data /var/lib/vz (this will be different in your file system)
Unable to get local IP address
/etc/init.d/pve-cluster restart service pve-cluster start Starting pve cluster filesystem : pve-cluster[main] crit: Unable to get local IP address (warning).
Make sure in /etc/hosts your domain name resolves to the server and you also have it without the .co.uk/.com etc in the file as so:
ServerIPaddress domain.co.uk domain pvelocalhost 127.0.0.1 localhost localhost.localdomain
Then do:
/etc/init.d/hostname.sh stop /etc/init.d/hostname.sh start service pve-cluster start
Transport endpoint is not connected
df -h df: `/etc/pve': Transport endpoint is not connected
ls -lah /etc/pve ls: cannot access pve: Transport endpoint is not connected d????????? ? ? ? ? ? pve
Do this:
umount /etc/pve pvecm status
You will get:
unable to get IP for node 'hostname' - node offline?
The fix is the same as this one, ensure you have the domain without the web extension in /etc/hosts resolving to the servers IP address. Then do:
service pve-cluster start
Recover deleted files
You need to install this software before you delete any files:
apt-get install foremost
Then see this documentation:
https://help.ubuntu.com/community/DataRecovery
http://ddailygirl.wordpress.com/2010/08/17/recovering-files-after-rm-in-linux
http://www.howtoforge.com/recover-deleted-files-with-foremost
http://www.webupd8.org/2009/03/recover-deleted-files-in-ubuntu-debian.html
Remove file starting with dash
rm -- -filename
Remove folder starting with dash
rm -rf -- -folder/
Remove/rename file called tilde
mv '~' newfilename rm '~'
Restart service or service
Useful for differently named ones, e.g.
[ -f /etc/init.d/mysqld ] && service mysqld restart ; [ -f /etc/init.d/mysql ] && service mysql restart
[ -f /etc/init.d/httpd ] && service httpd restart ; [ -f /etc/init.d/apache2 ] && service apache2 restart
Roughly list file count
This includes nested directories:
find /full/file/path -type f | wc -l
SCP Command - Secure Copy
To secure copy a file from one Linux server to another, use the following syntax form:
scp -P PORT file user@IPAddress:/filepath
For example:
scp -P 22 index.html [email protected]:/
To move a folder, put -r in between the port and the folder. If you receive the following error while trying to SCP a file from one server to the other:
stdin: is not a tty
You can solve the issue quickly by doing the following on the destination server:
vi ~/.bashrc if [ $(expr index "$-" i) -eq 0 ]; then return fi
Screen
Re-join screen session
screen -r
or
screen -D -r '1234.somescreensession'
A better alternate is tmux.
Manage Multiple sessions in one Terminal
Scrollback (vim /home/.screenrc + defscrollback 1000)
Tips and Tricks
Setting the time
http://geoffhankerson.com/node/112
http://codeghar.wordpress.com/2007/12/06/manage-time-in-ubuntu-through-command-line/
Standard redirection
http://www.xaprb.com/blog/2006/06/06/what-does-devnull-21-mean/
STDIN, STDOUT and STDERR.
0, 1 and 2
1>/dev/null
2>/dev/null
sudo
If you exit out of root access and want to run the last command you entered without authentication, do:
sudo !!
System Logs and Shutdown troubleshooting
If you are having an issue, a reboot should not be performed if the server can be accessed in any way (e.g. locally in the data centre, only if it is a Dedicated server). This is because after a reboot there is little you can find out from the logs as the important logs get cleared on restart.
last reboot last
Do this to check which files exist:
ls -lh /var/log/syslog ; ls -lh /var/log/kern.log ; ls -lh /var/log/dmesg ; ls -lh /var/log/messages
Then do one or more of these depending on which exist:
grep -i error /var/log/syslog ; grep -i panic /var/log/syslog ; grep -i warning /var/log/syslog
grep -i error /var/log/dmesg ; grep -i panic /var/log/dmesg ; grep -i warning /var/log/dmesg
grep -i error /var/log/kern.log ; grep -i panic /var/log/kern.log ; grep -i warning /var/log/kern.log
grep -i error /var/log/messages ; grep -i panic /var/log/messages ; grep -i warning /var/log/messages
errpt may show an error report on some Unix OS'.
To find .log files, run updatedb and then locate *.log
To restart and on boot do a disk check do (or -rF):
shutdown -Fr now
tar command
To archive and compress a folder/files do:
tar -czvf files.tgz files/ tar -czvf folder.tar.gz folder/ tar cvf mubackup.tar mu/ ; gzip -9 mubackup.tar #.tgz is same as .tar.gz
c creates the archive (tar), z compresses it into the gzip, v is verbose, f is the file/folder
To extract do:
#for tar tar xvf file.tar #for .tgz or tar.gz tar zxvf file.tar.gz
For bz2 files, use:
tar -xvjpf file
top
The TIME column in top is displayed in minutes:seconds.hundredths
tmux
New session
tmux new-session -n NameTheSession
Detach from a session
CTRL +B then D
Kill session
tmux kill-session -t myname
If this fails and it says:
"session not found"
Do the following:
tmux ls tmux kill-session -t X
- where X is the number of the session on the left.
List sessions available
tmux ls
Re-attach to session
tmux attach tmux attach -t ID or NameTheSession
Remotely execute a command
tmux send-keys -t ID "command" ENTER
User ID 99
This is most commonly the user nobody. This can be caused by PHP or done on purpose. cat /etc/passwd | grep 99 ; vim /etc/passwd
User is not in the sudoers file
If you try to sudo into a server or run sudo and get the following message:
"is not in the sudoers file. This incident will be reported."
Do the following command as root and add the username into the file in the same format as the root user:
visudo
Use unusual characters in filenames
If you want to specify a space, lets say the file = /usr/local/etc/testingdatabase.sql
You need to name the file/folder as follows:
mv /usr/local/etc/testingdatabase.sql /usr/local/etc/testing\ database.sql
This will make the file be testing database.sql , on command line this will appear as testing\ database.sql .
A backslash symbol \ needs to be used before an apostrophe ' , bracket (), exclamation/bang ! symbol or question marks ?:
01\ -\ It\'s\ You.txt #How it appears: 01 - It's You.txt 02\ -\ Boom\!.m3u #How it appears: 02 - Boom!.m3u 03\ -\ Why\ Wont\ You\ Work\?.sh #How it appears: 03 - Why Wont You Work?.sh 04\ -\ Musical\ Playlist\ For\ \(VPS\)\ Server.m3u #How it appears: 04 - Musical Playlist For (VPS) Server.m3u
updatedb (locate command)
This command is used when you cannot locate a file and you get "locate: warning: database /var/lib/slocate/slocate.db' is more than 8 days old". It is advised to run updatedb at least once a month. However if you get the following error when using it:
updatedb: fatal error: load_file: Could not open file: /etc/updatedb.conf: No such file or directory
You need to create or edit this file
vim /etc/updatedb.conf
and put the following inside of it:
PRUNE_BIND_MOUNTS="yes"PRUNEPATHS="/tmp /var/spool /media"PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre_lite tmpfs usbfs udf"
Alternatively run the below script after reading this file http://serverkb.co.uk/tools/README.txt:
http://serverkb.co.uk/tools/updatedbscript.sh
To vim a file you locate, see this. vim $(command)
Cannot find an existing file
Ensure that the directory path of the file that does exist is not in the following section in /etc/updatedb.conf:
PRUNEPATHS="/tmp /var/spool /media"
vim
To make a copy the line below where you cursor is, hold CTRL + e. Then put a hash (comment) in front of this line. This is useful for backing up an old value before changing it.
Create backup of file whilst in vim
vim file :!cp % %-
Press enter and continue to edit
Credit to User MPB
Enter Insert mode
Press the letter i (I)
Enter Replace mode
Press the letter r (R)
E21: Cannot make changes, 'Modifiable' is off
:set modifiable
See changes made before exiting
:w !diff % -
Editing a jar/zip file
(zip#Write) sorry, your system doesn't appear to have the zip pgm
:set modifiable :set write
E382: Cannot write, 'buftype' option is set
Check if the file has -e on it using:
lsattr filename
If so, you cannot edit it.
VPS Hints and Tips
To check for the filepath of a command run top and then press c.
If it is a container on a node, there are generally no datacentre / rack level restrictions as the container is virtualised on a node. The only restrictions are what is put in place via the container itself effectively.
To list all open Internet, x.25 (HP-UX), and UNIX domain files, use:
lsof -i -U
WHOIS script
apt-get install pv ; cd /var/www/vhosts ; ls -l | awk ' {print $9}' > domainlist ; wget serverkb.co.uk/tools/findregistrar.sh ; chmod +x findregistrar.sh
For CentOS use yum -y install jwhois.x86_64
Edit the file and replace domain registrar with the one you want to find. Then do:
./findregistrar.sh
write error
If you get the following error when doing write user TTYsession or write user Session:
write: write: you have write permission turned off.
Do this to fix the problem:
mesg y