Simple script for starting, reloading and stopping nginx.

Simple script for starting, reloading and stopping nginx.

For simple use put it in one of the folders listed when running.

echo $path

The script


if [[ -z $1 ]]
elif [[ $1 == "start" ]]
$binpath/nginx -s $1

if [[ $? == 0 ]]
echo "$action successfull"
echo "$action failed"

Then use it the following ways.

nginx start
nginx reload
nginx stop

Howto setup openvpn on ubuntu 14.04

Install openvpn and create keys.

Use aptitude to download and install openvpn and required software.

apt-get install bridge-utils openvpn easy-rsa

Create easy-rsa key creating directory.

make-cadir /etc/openvpn/easy-rsa

Edit vars file with commonname etc. for your certficate.

nano /etc/openvpn/easy-rsa/vars

Edit the following to your needs.

export KEY_PROVINCE="Somewhere"
export KEY_CITY="somecity"
export KEY_ORG="somename"
export KEY_EMAIL=""

Vars file is also where you specify key strenght, you can set this to 4096 for increased security.

Start creating keys for server

cd /etc/openvpn/easy-rsa/
source vars
./pkitool --initca
./pkitool --server server
cd keys
openvpn --genkey --secret ta.key

Copy keys to openssl config folder.

cp server.crt server.key ca.crt dh4096.pem /etc/openvpn/

create keys for client, in this example we will call this client for bob.

cd ..
source vars
./pkitool bob

Download bobs keys to your computer as we will need them when creating bobs openvpn config file.

Configure openvpn on server.

Edit /etc/openvpn/openvpn.conf in this example i have ip range

dev tap
proto udp
port 1194
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh4096.pem
user nobody
group nogroup
status /var/log/openvpn-status.log
verb 3
keepalive 10 120
log-append /var/log/openvpn
auth SHA1
cipher AES-256-CBC

start openvpn server

/etc/init.d/openvpn start

If something doesnt work check /var/log/openvpn and consult comment field below or google.

Create config file for openvpn client.

for simplicity i will still use bob as an example, and now we need to create a file called bob.ovpn and fill it with the following.

dev tap
proto udp
remote 1194

#          RC2-40-CBC RC2-64-CBC RC2-CBC
#  auth:   SHA SHA1 MD5 MD4 RMD160

cipher AES-256-CBC
auth SHA1

resolv-retry 1
verb 3







Now we need to chance domain name from to your domain name or ip adress.

As you can see in the config above there are some fields called and and so forth, this is where we will copy inn the certificated we created for bob and stored on our computer.
in between the and we will enter everyting between “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” also including those two from the ca.crt which you can find in /etc/openvpn/ca.crt

The procedure is the same for and although bob.crt will fill out and bob.key will fill out


And thats all, copy config file into openvpn config file folder and start openvpn and you will connect to your lan via vpn.

A quick howto on mod_security rules.

no image caption

This howto does not cover installation of mod_security, it will only cover the finer points about rules and how to write your own custom ones 🙂
A ModSecurity rule does consist of the following.

Always consult the reference manual when writing rules, it covers everything you need.

Directive : Eg. SecRule for rules duh…
Scanfiler : REQUEST_URI or USERAGENT etc. full list here.
Scantarget : For example this can be googlebot when checking for useragent.
Action : What to do if filter fount a hit, Eg. Deny, Pass, Allow, log. It also has to contain a unique ID. full list here.

Some actions and scanfilters have prerequisites to work, and they are mostly documented in reference manual.
To start with you can add the following modsecurity rules in modsec config before including custom rules.

SecDataDir /tmp/sectmp
SecTmpDir /tmp
SecAuditLogDirMode 0777
SecPcreMatchLimit 1500
SecPcreMatchLimitRecursion 1500
SecCollectionTimeout 28800
SecRequestBodyAccess On
SecStreamInBodyInspection On
SecHashEngine On
SecRequestBodyInMemoryLimit 1310720

With this set you can forexample store connection ip adresses for up to 8 hours (28800 sec.) and to make a comparison you can say this is a form of session, which you can store session data upon.
With ModSecurity you can have a rule which store a variable on top of a ip, with this you can for example store how many times in the last 10 minutes someone has visited a page on you webpage.

Lets make an example like that.

First we need to start storing a “Session” for every visiting ip address.
This you can do with ACTION initcol like so.

SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:1370

Then we can start storing information, lets say we will store how many times googlebot visit us total for up to 8 hours, when it will be reset.

SecRule REQUEST_HEADERS:User-agent "googlebot" "phase:1,nolog,id:1371,setvar:ip.counter=+1,pass"

We can then use this information to block googlebot requests if over 10 requests in last 8 hours.

SecRule ip:counter "@gt 10" "phase:1,log,msg:'googlebot has been blocked due to over 10 requests.',deny,id:1372"

You can also use AND in rules, in modsec this is done by using chains. Chained rules do not require ID.
Let say we will only block googlebot when it has over 10 requests and is visiting a specific file.

SecRule ip:counter "@gt 10" "phase:1,log,msg:'googlebot has been blocked due to over 10 requests.',deny,id:1372,chain"
SecRule REQUEST_URI "somefile.php" "t:none"

With this you should have grasped how modsecurity rules are written, and with the reference manual you can start doing magic 🙂

Setting up IET (iSCSI Enterprise Target) on homeserver for vmware hypervisor.

Create folder for disk binary file.

mkdir -p /d2

Create binary disk file.

dd if=/dev/zero of=/d2/ds1.bin count=0 obs=1 seek=50G

Edit  /etc/iet/ietd.conf and insert text below.

Target iqn.2012-05.local.mynet:storage.sys0
Lun 0 Path=/d2/ds1.bin,Type=fileio,ScsiId=lun0,ScsiSN=lun0

MaxConnections 1
MaxSessions 0 
InitialR2T Yes
MaxRecvDataSegmentLength 81920
MaxXmitDataSegmentLength 81920
MaxBurstLength 2621440
FirstBurstLength 655360
DefaultTime2Wait 2
DefaultTime2Retain 0
MaxOutstandingR2T 1
DataPDUInOrder Yes
DataSequenceInOrder Yes
ErrorRecoveryLevel 0
HeaderDigest None,CRC32C
DataDigest None,CRC32C
NOPInterval 0
NOPTimeout 0 # Wait that many seconds for a
Wthreads 2
QueuedCommands 320

If you get errors like this one below in syslog, you might need to up the vallues above.

iscsi_trgt: Abort Task (01) issued on tid:1 lun:0 by sid:282574492336640 (Function Complete)

If this limit has been reached your iscsi target wont answer again until target service has been restarted.

Additional config.

Chap mutual

IncomingUser incusername incpasswd
OutgoingUser outusername outpasswd

Skip outgoing for one way chap.

Add more luns to your target,  add the following lines right bellow lun 0 in config above.

Lun 1 Path=/d2/ds2.bin,Type=fileio,ScsiId=lun1,ScsiSN=lun1
Lun 2 Path=/d2/ds3.bin,Type=fileio,ScsiId=lun2,ScsiSN=lun2

Example varnish config for Joomla and WordPress

This example has a webserver running on the same server on port 8080, this can easlily be changed by editing host ip and port vallues bellow.

The config does also not cache when logged in.
Cache will only store cache content for 5 minutes.

backend webserver {
.host = "";
.port = "8080";
## Recieve
sub vcl_recv {
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
# If the browser supports it, we'll use gzip.
set req.http.Accept-Encoding = "gzip";
else if (req.http.Accept-Encoding ~ "deflate") {
# Next, try deflate if it is supported.
set req.http.Accept-Encoding = "deflate";
else {
# Unknown algorithm. Remove it and send unencoded.
unset req.http.Accept-Encoding;
# Forward client's IP to backend
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Proxy (pass) any request that goes to the backend admin,
# the banner component links or any post requests
# You can add more pages or entire URL structure in the end of the "if"
if(req.http.cookie ~ "userID" || req.http.cookie ~ "wordpress_logged_in" || req.url ~ "^/administrator" || req.url ~ "^/component/banners" || req.request == "POST" || req.url ~ "wp-(login|admin)") {
return (pass);
# Check for the custom "x-logged-in" header to identify if the visitor is a guest,
# then unset any cookie (including session cookies) provided it's not a POST request
if(req.http.x-logged-in == "False" && req.request != "POST"){
unset req.http.cookie;
# Properly handle different encoding types
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
# No point in compressing these
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unknown algorithm (aka crappy browser)
remove req.http.Accept-Encoding;
# Cache files with these extensions
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
return (lookup);
# Set how long Varnish will cache content depending on whether your backend is healthy or not
if (req.backend.healthy) {
set req.grace = 5m;
} else {
set req.grace = 1h;
return (lookup);
## Fetch
sub vcl_fetch {
# Check for the custom "x-logged-in" header to identify if the visitor is a guest,
# then unset any cookie (including session cookies) provided it's not a POST request
if(req.request != "POST" && beresp.http.x-logged-in == "False") {
unset beresp.http.Set-Cookie;
# Allow items to be stale if needed (this value should be the same as with "set req.grace"
# inside the sub vcl_recv {.} block (the 2nd part of the if/else statement)
set beresp.grace = 1h;
# Serve pages from the cache should we get a sudden error and re-check in one minute
if (beresp.status == 503 || beresp.status == 502 || beresp.status == 501 || beresp.status == 500) {
set beresp.grace = 60s;
return (restart);
# Unset the "etag" header (suggested)
unset beresp.http.etag;
if(beresp.http.Cache-Control == "no-cache" || beresp.http.Cache-Control == ""){
set beresp.http.Cache-Control = "max-age=300, public, must-revalidate";
# Don't allow static files to set cookies.
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$") {
# beresp == Back-end response from the web server.
unset beresp.http.set-cookie;
# Allow items to be stale if needed.
set beresp.grace = 6h;
unset beresp.http.Server;
set beresp.http.Server = "StarGazer";
## Remove the X-Forwarded-For header if it exists.
remove req.http.X-Forwarded-For;
remove req.http.X-Content-Encoded-By;
## insert the client IP address as X-Forwarded-For. This is the normal IP address of the user.
set    req.http.X-Forwarded-For = req.http.rlnclientipaddr;
## Deliver the content
set beresp.ttl = 300s;
set beresp.http.LiveForSec = beresp.ttl;
## Deliver
sub vcl_deliver {
## We'll be hiding some headers added by Varnish. We want to make sure people are not seeing we're using Varnish.
## Since we're not caching (yet), why bother telling people we use it?
remove resp.http.X-Varnish;
remove resp.http.Via;
remove resp.http.Age;
remove resp.http.Vary;
## We'd like to hide the X-Powered-By headers. Nobody has to know we can run PHP and have version xyz of it.
remove resp.http.X-Powered-By;