I found myself recently rebuilding my home server (again). In December, I lost a drive out of my LVM large disk array and felt that it was time to give CentOS a try at home. Try as I might, I just wasn’t a fan, and went back to Ubuntu 12.04 LTS. I tried to do an in-place upgrade (unadvised until 14.04.1 releases later this summer) and wound up being unsatisfied with the results. So, at the end of June, I began the arduous process of rebuilding to 12.04 and documenting the process along the way.
As a refresher, I have 2x 2TB Seagate hard drives that are setup in software RAID-0 (to create a 4TB “single” drive), and 1x 250gb hard drive. The OS is installed onto the 250gb, while the 4TB “disk” is mounted to “/data”. I use dyndns.com to provide a simple domain identity (since my router supports it). The rest of the internals on the box are inconsequential. The 4TB disk was created during the installation process.
At the end of the day, I have a home linux-based, headless server that I can use for web development, hosts an instance of GitLab CE, shares media via Samba and NFS, shares my printer amongst the multiple PCs, and of course can serve as a backup location for any of the computers in my house.
The majority of the install and tips comes from various tutorials on howtoforge.com. Those are:
Overall – http://www.howtoforge.com/perfect-server-ubuntu-12.04-lts-apache2-bind-dovecot-ispconfig-3
Samba – http://www.howtoforge.com/ubuntu-12.04-samba-standalone-server-with-tdbsam-backend
PHP-FPM – http://www.howtoforge.com/using-php5-fpm-with-apache2-on-ubuntu-12.04-lts
I know that I’m repeating quite a bit of the steps in some spots, and in other spots, being woefully inadequate.
After the installation from disk is done, while still physically at the terminal, I change the hostname and network interface to a static IP and make sure that I have SSH up and running before I disconnect the monitor and keyboard.
apt-get update && apt-get upgrade
apt-get install openssh-server ssh
apt-get update && apt-get install samba cups
nano /etc/samba/smb.conf
Edit the file, looking for following (change values as necessary):
security = user map to guest = bad user passdb backend = tdbsam
Make sure to have blocks for “other” shares (such as the music folder)
[Music] comment = Music, Mp3's path = /music force user = username force group = usergroup read only = No guest ok = Yes public = yes browseable = yes
Don’t forget to allow your “home” directories available. Mine are set to be hidden unless the user is “logged in” on Windows – (just uncomment the lines)
# Un-comment the following (and tweak the other settings below to suit) # to enable the default home directory shares. This will share each # user's home director as \\server\username [homes] comment = Home Directories browseable = no # By default, the home directories are exported read-only. Change the # next parameter to 'no' if you want to be able to write to them. read only = no
Make sure to restart samba (or reboot) before trying to connect to the shares.
service smbd restart
Now add your user account into samba (you’ll be asked for the password).
smbpasswd -a user
I also set up NFS file sharing/serving because for some strange reason, my HTPC has issues with Samba.
apt-get install nfs-kernel-server portmap
For me, it’s as simple as editing /etc/exports and adding the following line:
/data 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
After that, just run
exportfs -a
Now, onto setting up shared printing through CUPS.
nano /etc/cups/cupsd.conf
You’ll be editing the following areas to look like this –
# Only listen for connections from the local machine. Listen *:631 <--- change this Listen /var/run/cups/cups.sock # Restrict access to the server... <Location /> #Require valid-user Order Deny,Allow Deny From ALL Allow From 127.0.0.1 Allow From 192.168.1.0/24 </Location> # Restrict access to the admin pages... <Location /admin> Order Deny,Allow Deny from ALL Allow From 127.0.0.1 Allow From 192.168.1.0/24 </Location> # Restrict access to configuration files... <Location /admin/conf> AuthType Default Require user @SYSTEM Order Deny, Allow Deny from ALL Allow from 127.0.0.1 Allow from 192.168.1.0/24 </Location>
What we’ve done here is limited the access to just local ip’s on our subnet. (This is just htaccess editing.) Given that I don’t allow access to port 631 outside of my router anyways, this is overkill for me, but your setup may differ. Make sure you’ve changed the 127.0.0.1 to “*” so it listens on all interfaces. Once you’re done, make sure you can access the CUPS server by visiting serverip:631 in a browser.
If you want, you can add the printer now (assuming it’s plugged in) by following the fairly straightforward interface. Once the printer is setup, from your windows computers, click on the “printers” tab and right click & copy the link for the printer. When you go to setup on your Windows box, you’ll go to Start -> Devices and Printers -> Add Printer -> Add Network printer. Click “printer that I want isn’t listed” and select the 2nd option. Paste the address in the box, making sure to change the https:// to http://. Follow the rest of the steps and you should be good to go.
Onto the web server stuff. Most tutorials suggest that you setup in /var/www (or /var/www/html if on CentOS). While this is certainly convenient, I find that it doesn’t really mimic the feel of being on a shared hosting platform, or even just running multiple sites on the same server. I prefer running out of userdirs (like on shared hosts). To save some time when adding users later, edit the skeleton setup file to include a public_html folder.
mkdir /etc/skel/public_html
Now when you setup a new user, there will automatically be a “public_html” folder.
apt-get install mysql-server mysql-client
Follow the on-screen prompts to set your mysql root password (different from your root password). Now, onto Apache & PHP-FPM.
apt-get install apache2-mpm-worker
apt-get install libapache2-mod-fastcgi php5-fpm php5
a2enmod actions fastcgi alias rewrite
service apache2 restart
Now to set Apache to use fastcgi and php-fpm. I prefer this method because it’s somewhat (and I use that term loosely) similar to setting up for NGINX. It’s also less of a headache than running suexec/suphp and mod_php or using httpd_itk/apache2-itk. If you eventually branch out to a VPS and want to use the new SPDY protocol, this is a MUST (using suexec/suphp or php-fpm).
nano /etc/apache2/conf.d/fastcgi.conf
<IfModule mod_fastcgi.c> AddHandler php5-fcgi .php Action php5-fcgi /php5-fcgi Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization </IfModule>
and edit /etc/php5/fpm/pool.d/www.conf and change the following section: (you’re commenting out the port and creating a unix socket). I prefer running my sockets out of the /tmp directory, but that’s me.
;listen = 127.0.0.1:9000 listen = /tmp/php5-fpm.sock
We need to make sure that the default pool also can work across all undefined hosts (just in case)
; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many ; BSD-derived systems allow connections regardless of permissions. ; Default Values: user and group are set as the running user ; mode is set to 0666 listen.owner = www-data listen.group = www-data ;listen.mode = 0666
Also, we need to define the session save path at the end of the file. Add the following line –
php_admin_value[session.save_path] = /var/lib/php5/www
And make the directory, while assigning it to the www-data user (so the PHP applications can stay “logged in”).
mkdir /var/lib/php5/www && chown www-data:www-data /var/lib/php5/www
Restart PHP-FPM
service php5-fpm restart
Now install some extra PHP things…
apt-get install php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl
We also install APC caching
apt-get install php-pear php5-dev make libpcre3-dev
pecl install apc
Now we need to edit php.ini
nano /etc/php5/fpm/php.ini
add the following at the end:
[apc] extension=apc.so apc.write_lock = 1 apc.slam_defense = 0
And we install phpMyAdmin
apt-get install phpmyadmin
Select “apache2” and decline the dbconfig-common option.
Now, onto configuring the server to use the /home/user/public_html directory. We’ll copy the default fpm pool and make some changes.
cp /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/pool.d/user.conf
edit the user.conf and we’re going to change just a few things at the moment…
;pool name ('www' here) [user] user = username group = usergroup
listen = /tmp/php5-fpm-user.sock
It’s important that you also uncomment and modify the “listen.owner” and “listen.group” lines, so that when all is said and done, if you run WordPress, you can do file modifications and such from the admin area.
php_admin_value[session.save_path] = /var/lub/php5/user
mkdir /var/lib/php5/user && chown user:user /var/lib/php5/user
Now we set up our “default” site to point to the user directory.
nano /etc/apache2/sites-available/default
The final result should look something like this (bold is the changes)
<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName examples.com ServerAlias *.example.com DocumentRoot /home/user/public_html <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /home/user/public_html> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/user-error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/user-access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory> <IfModule mod_fastcgi.c> AddHandler php5-fcgi .php Action php5-fcgi /php5-fcgi Alias /php5-fcgi-user /usr/lib/cgi-bin/php5-fcgi-user FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi-user -socket /tmp/php5-fpm-user.sock -pass-header Authorization </IfModule> </VirtualHost>
The ServerName and ServerAlias bits are important, especially if you plan to use WordPress in multisite mode for development. Servername is necessary any time you want to run multiple sites (like gitlab below).
While I don’t use my home box as a true email server, I do have postfix installed and routed through Mailjet (a free service) to deliver any service mails. I use a service from mailjet to ensure deliverability for my real email server, so I just use that for the home box as well. Mailjet is free for the first 6,000 emails per month, so I highly recommend it for something like this. You can also use a gmail account as a relayhost (not covered here).
apt-get install postfix
Configuration options:
Internet with smarthost SMTP relay: in.mailjet.com
Next, you’ll need to edit /etc/postfix/main.cf
and add the following lines at the end:
smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous smtp_sasl_password_maps = hash:/etc/postfix/saslpasswd smtp_always_send_ehlo = yes
Next we’ll need to create that saslpasswd file, and it should look like this:
in.mailjet.com username:userpassword
(Keep in mind the username/pass is actually a long string, and NOT what you log into mailjet with).
Now just run postmap /etc/postfix/saslpasswd
and restart postfix.
I started to use git versioning for my projects, and rather than using the hosted platform, I run my own Gitlab instance. (Totally optional.)
I followed the install instructions from https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md up until section 6 (NGINX). Since I use apache, there’s a few differences in the setup at this point.
a2enmod proxy proxy_balancer proxy_http rewrite
gem install passenger
passenger-install-apache2-module
At the end of the install, it will have a few lines you’ll need to add to the apache config files (or vhost files). My vhost file looks something like below –
LoadModule passenger_module /usr/local/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so <IfModule mod_passenger.c> PassengerRoot /usr/local/lib/ruby/gems/2.1.0/gems/passenger-4.0.45 PassengerDefaultRuby /usr/local/bin/ruby </IfModule> <VirtualHost *:80> ServerName gitlab.example.com # !!! Be sure to point DocumentRoot to 'public'! DocumentRoot /home/gitlab/gitlab/public <Directory /home/gitlab/gitlab/public> # This relaxes Apache security settings. AllowOverride all # MultiViews must be turned off. Options -MultiViews </Directory> </VirtualHost>
For the final step, install fail2ban. I feel this is important because it will attempt to limit “brute force” SSH attacks against your server.
apt-get install fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit the jail.local as you see fit. The defaults aren’t too bad, but one of the things I found was I was getting emails every ban that was executed on my CentOS servers. All the lines that have “sendmail” as an action I deleted from my configs. On Ubuntu, you’ll need to delete the lines that start with:
%(mta)s-whois
(commenting those out seemed to throw errors for me). Make sure you’ve enabled fail2ban on startup: update-rc.d fail2ban defaults.
I don’t run a traditional FTP server (security reasons), and find that SFTP over SSH works just fine for what little I do.