What is Lemonstand

If you have ever trawled the interwebs for a half decent Ecommerce solution chances are you have encountered PHP based solutions like Magento, OSCommerce, OpenCart etc. These are quite well established players but a recent addition to the gang has really impressed us and a bunch of other like minded people too. Lemonstand feels lightweight yet powerful, the core covers the shop fundamentals very well and it is supported by a growing community. Check out the video.

Lemonstand Introduction

This is the first part in a multi part post that will hopefully finish up with a production ready virtual machine running Lemonstand for your online store.

Ubuntu and VMWare Fusion

First things first, you have to run up a new virtual machine. Eventually you will do this with some cloud provider (OrionVM, RackSpace etc) but for development or testing your configuration a local VM is all you need. Note that there are VMWare alternatives and in this case you could use the excellent VirtualBox from Sun/Oracle http://www.virtualbox.org.

After Ubuntu is installed in Fusion

Depending on what route you took with installing Ubuntu on a local VM (simple or manual) theres a chance SSH might not be installed. If this is the case just work directly in the console for now. First thing you need to do is login with the username and password you configured.


I had to reset the keyboard as command repeat didn’t work on Fusion/Ubuntu 10.04

Type the following and accept the defaults.

sudo dpkg-reconfigure console-setup


Reset your password if either logging in as root or you accepted some default password


you can also change another users password by appending their username to the command


passwd devuser

Even though we won’t be allowing root to login via SSH, we want to make sure it has a strong password.

Type this command and enter your new strong password twice.

sudo passwd root

Remove non essential accounts from etc/passwd, you likely don’t require games,news,list,irc,gnats


Also set the users shell to /bin/false

You could also change the shell like this (for the user ‘list’)

chsh -s /usr/sbin/nologin list

Verify No Accounts Have Empty Passwords

sudo awk -F: '($2 == "") {print}' /etc/shadow

Lock all empty password accounts

passwd -l account_name

Make Sure No Non-Root Accounts Have UID Set To 0

sudo awk -F: '($3 == "0") {print}' /etc/passwd

You should see a single line like this:



Set the correct timezone for your location.

dpkg-reconfigure tzdata



echo "Australia/Adelaide" | sudo tee /etc/timezone. sudo dpkg-reconfigure --frontend noninteractive tzdata

Hostname and hosts file

Set the correct hostname by editing the “hostname” file.

sudoedit /etc/hostname

Check hosts file as default can sometimes be Ubuntu depending on how you installed the OS.

You should have a line that contains your IP address and then your long hostname separated by a space then your hostname on its own.

Running “hostname –f” should return the long version.

sudoedit /etc/hosts
…	localhost	cortina.example.com cortina

Configure admin group

Check that your part of the admin group

cat /etc/group



grep devuser /etc/group

you should see a line like this (the number 109 may differ), this means the user ‘devuser’ is a member of the admin group.


If the admin group doesn’t exist or your not a member of it follow these steps.

sudo groupadd admin sudo usermod -a -G admin devuser

Configure sudo

Edit the sudo configuration

sudo /usr/sbin/visudo

Check that the admin group has full sudo privileges, add this line if it doesn’t exist.


%admin ALL=(ALL) ALL

Restrict access to /bin/su to admin group members


sudo dpkg-statoverride --update --add root admin 4750 /bin/su

Secure shared memory

/dev/shm can be used in an attack against a running service, such as httpd. Modify /etc/fstab to make it more secure.

sudo nano /etc/fstab

Add this line


tmpfs /dev/shm tmpfs defaults,noexec,nosuid 0 0

Remount /dev/shm or reboot


sudo mount -o remount /dev/shm

Setup SSH server

Install SSH server & client

sudo apt-get install openssh-client sudo apt-get install openssh-server

Backup original config file and make read only

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig sudo chmod a-w /etc/ssh/sshd_config.orig

Edit SSH server config file and make the following changes:

sudoedit /etc/ssh/sshd_config

Disable root login but allow forced commands


PermitRootLogin forced-commands-only

Reduce the login grace time


LoginGraceTime 20

The SSH daemon will allow a message to be displayed to users attempting to log in to the SSH server. To enable login messages, remove the pound sign from this line:


Banner /etc/issue.net

Hide “Ubuntu” from the OpenSSH headers


DebianBanner no

Add line for allowed users


AllowUsers devuser

Update the login warning in the file “/etc/issue.net”


sudoedit /etc/issue.net

Restart SSH


sudo /etc/init.d/ssh restart

You can now login to the server using Putty on Windows or the built-in SSH client on OSX and Linux.

Harden TCP/IP Stack

Some of these will be set by default anyway but it doesn’t hurt to check.

These commands change the current runtime variables only, to make them persist edit the following file

sudoedit /etc/sysctl.conf

Disable ICMP broadcast echo activity.

 sudo sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 

Disable ICMP routing redirects. Otherwise, your system could have its routing table misadjusted by an attacker.

 sudo sysctl -w net.ipv4.conf.all.accept_redirects=0 sudo sysctl -w net.ipv4.conf.all.send_redirects=0 

Disable IP source routing. The only use of IP source routing these days is by attackers trying to spoof IP addresses that you would trust as internal hosts.

 sudo sysctl -w net.ipv4.conf.all.accept_source_route=0 sudo sysctl ­-w net.ipv4.conf.default.accept_source_route=0 sudo sysctl -w net.ipv4.conf.all.forwarding=0 

Enforce sanity checking, also called ingress filtering or egress filtering.

sudo sysctl -w net.ipv4.conf.all.rp_filter=1

Log and drop “Martian” packets.

sudo sysctl -w net.ipv4.conf.all.log_martians=1

Randomize your address space

sudo sysctl ­-w kernel.randomize_va_space = 1

Setup NTP

Install NTP support

sudo apt-get install ntp

Change the contents of /etc/ntp.conf to include additional server lines. Use a different pool if not in Australia.

 server 0.au.pool.ntp.org server 1.au.pool.ntp.org server 2.au.pool.ntp.org server 3.au.pool.ntp.org 

Restart ntp process

sudo /etc/init.d/ntp restart

You can check the status of peers by running


/usr/bin/ntpq -np

File security

Check for World-Writable files and investigate.

find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print

Find any files not owned by any user or group.

find / -xdev \( -nouser -o -nogroup \) -print

Enable and configure firewall

UFW is Ubuntu’s “uncomplicated firewall”, it just simplifies the setup of iptables rules.

Install UFW and set the default mode to deny.

sudo apt-get install ufw sudo ufw default deny


sudo ufw allow 22 sudo ufw allow 80 sudo ufw allow 443 

Enable UFW


sudo ufw enable

Switch on logging.


sudo ufw logging on

By default, UFW allows ping requests. To disable You need to edit /etc/ufw/before.rules and remove or edit the following lines: Change ‘ACCEPT’ to ‘DROP’

# ok icmp codes -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT -A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT