Skip to content

Instantly share code, notes, and snippets.

@markahesketh
Last active June 26, 2022 20:35
Show Gist options
  • Save markahesketh/6090388 to your computer and use it in GitHub Desktop.
Save markahesketh/6090388 to your computer and use it in GitHub Desktop.
LAMP stack on Linode
#!/bin/bash
# ==============================================================================
# Set up LAMP stack on blank Linode
#
# $ nano install.sh
# Copy/paste this script into terminal. Save and exit.
# $ chmod 775 install.sh
# $ ./install.sh
# $ rm install.sh
# ==============================================================================
# Check we're using root user
if [ $(id -u) -eq 0 ]; then
# Getting started
# ------------------------------------------------------------------------------
# Get required options
read -p "New hostname (e.g. pluto): " HOSTNAME
read -p "Main domain (e.g. example.com): " DOMAIN
# Get config
IP="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
# Add additional sources
echo "deb http://us.archive.ubuntu.com/ubuntu/ quantal multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ quantal multiverse
deb http://us.archive.ubuntu.com/ubuntu/ quantal-updates multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ quantal-updates multiverse" >> /etc/apt/sources.list
# Update all the packages
echo "Updating packages..."
apt-get update && apt-get --yes --force-yes upgrade
sleep 1
# Add the hostname
echo "Configuring hostname..."
echo "${HOSTNAME}" > /etc/hostname
hostname -F /etc/hostname
# Add hostname and FQDN to hosts
cp /etc/hosts /etc/hosts.original
echo -e "${IP}\t${HOSTNAME}.${DOMAIN}\t${HOSTNAME}" >> /etc/hosts
sleep 1
# Set timezone
echo "Setting timezone..."
dpkg-reconfigure tzdata
sleep 1
# Security
# ------------------------------------------------------------------------------
clear
echo "Starting security settings..."
read -p "Choose server admin username (e.g. user1): " ADMINUSER
adduser $ADMINUSER
usermod -a -G sudo $ADMINUSER
clear
read -p "################################################################################
## IMPORTANT ###################################################################
################################################################################
We're about to disable root and password logins.
You need to set up SSH key pair authentication for ${ADMINUSER}.
** DO THIS BEFORE CONTINUING OR YOU WILL BE LOCKED OUT OF THE SERVER **
Use the following command in your LOCAL terminal:
scp ~/.ssh/id_rsa.pub ${ADMINUSER}@${IP}:
Note: Use the password specified when creating the user account.
Confirm SSH key pair set up (Y/n)?" CONT
if [ "$CONT" == "Y" ] || [ "$CONT" == "y" ]; then
# Move and modify permissions of public key
mkdir /home/$ADMINUSER/.ssh
mv /home/$ADMINUSER/id_rsa.pub /home/$ADMINUSER/.ssh/authorized_keys
chown -R $ADMINUSER:$ADMINUSER /home/$ADMINUSER/.ssh
chmod 700 /home/$ADMINUSER/.ssh
chmod 600 /home/$ADMINUSER/.ssh/authorized_keys
# Stop password authenticated and root login
echo "Stopping password authentication and root login for SSH..."
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
echo "... done. I hope you have an SSH key pair set up!"
fi
sleep 1
# Choose a new SSH port
read -p "Choose a new SSH port (below 1024 but not 22): " SSHPORT
# Set SSH to use the chosen port
sed -i "s/Port 22/Port ${SSHPORT}/g" /etc/ssh/sshd_config
echo "Setting up firewall..."
# Set up firewall rules
echo "*filter
# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT
# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allow SSH connections
#
# The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport ${SSHPORT} -j ACCEPT
# Allow ping
-A INPUT -p icmp -j ACCEPT
# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix \"iptables denied: \" --log-level 7
# Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT" > /etc/iptables.firewall.rules
# Apply firewall rules
iptables-restore < /etc/iptables.firewall.rules
# Load firewall rules on server start up
echo "#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules" > /etc/network/if-pre-up.d/firewall
chmod +x /etc/network/if-pre-up.d/firewall
sleep 1
# Install fail2ban
echo "Installing and configuring fail2ban..."
apt-get --yes --force-yes install fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Set new SSH ports in fail2ban config
sed -i "/enabled = false/{ N; s/enabled = false\nport = ssh/enabled = true\nport = ${SSHPORT}/ }" /etc/fail2ban/jail.local
sed -i "s/port = ssh/port = ${SSHPORT}/g" /etc/fail2ban/jail.local
service fail2ban restart
# Set up jailed sftp user accounts
echo "Setting up SFTP jails..."
addgroup sftp
sed -i 's/Subsystem sftp \/usr\/lib\/openssh\/sftp-server/Subsystem sftp internal-sftp/g' /etc/ssh/sshd_config
echo "
Match group sftp
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
PasswordAuthentication yes" >> /etc/ssh/sshd_config
# Add SFTP group for jailed accounts
addgroup sftp
# Create www directory and set permissions to lock out users
mkdir /srv/www
chown root:root /srv/www
# Restart SSH service
service ssh restart
sleep 1
# Apache
# ------------------------------------------------------------------------------
clear
echo "Installing Apache"
sleep 2
sudo apt-get --yes --force-yes install apache2
echo "... Apache installed."
sleep 1
echo "Configuring Apache"
# Backup original config
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.original
# Disable default site
a2dissite default
# Enable rewrites
a2enmod rewrite
service apache2 restart
# MySQL
# ------------------------------------------------------------------------------
clear
echo "Installing MySQL..."
sleep 2
apt-get --yes --force-yes install mysql-server
clear
echo "Running mysql_secure_installation. Use SQL login details"
mysql_secure_installation
sleep 1
# Backup original config
echo "Backing up MySQL config"
cp /etc/mysql/my.cnf /etc/mysql/my.cnf.original
service mysql restart
# PHP
# ------------------------------------------------------------------------------
clear
echo "Installing PHP, PHP Extensions and APC..."
sleep 2
# Install PHP
apt-get --yes --force-yes install php5 php-apc php5-cli php5-dev php5-curl php5-gd php5-geoip php5-imagick php5-imap php5-intl php5-mcrypt php5-memcache php5-ming php5-mysql php-pear php5-ps php5-pspell php5-recode php5-snmp php5-suhosin php5-tidy php5-xmlrpc php5-xsl make libpcre3-dev libssh2-php
# Restart apache
service apache2 restart
# Backup original config
echo "Backing up PHP config"
cp /etc/php5/apache2/php.ini /etc/php5/apache2/php.ini.original
# Postfix
# ------------------------------------------------------------------------------
clear
echo "Installing Postfix..."
sleep 2
apt-get --yes --force-yes install postfix
# Logwatch
# ------------------------------------------------------------------------------
clear
echo "Installing Logwatch..."
sleep 2
read -p "Admin e-mail that should receive log reports domain (e.g. admin@example.com): " LOGWATCHEMAIL
# Install logwatch
apt-get --yes --force-yes install logwatch
# Configure to send logs to email
sed -i 's/Output = stdout/Output = mail/g' /usr/share/logwatch/default.conf/logwatch.conf
sed -i 's/Format = text/Format = html/g' /usr/share/logwatch/default.conf/logwatch.conf
sed -i "s/MailTo = root/MailTo = ${LOGWATCHEMAIL}/g" /usr/share/logwatch/default.conf/logwatch.conf
sed -i "s/MailFrom = Logwatch/MailFrom = logwatch@${DOMAIN}/g" /usr/share/logwatch/default.conf/logwatch.conf
# Final update of packages
# ------------------------------------------------------------------------------
apt-get --yes --force-yes install unzip
apt-get update && apt-get --yes --force-yes upgrade
# Remove install script
rm install.sh
clear
echo "################################################################################
## FINISHED ####################################################################
################################################################################
Now optimise Apache, MySQL and PHP for your linode.
For 1GB Linode see gist: https://gist.github.com/heskethm/6089959
"
# If not ROOT
else
echo "Switch to root user first."
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment