In this guide, we will set up your home Linux server to share files in a Windows-friendly format. This is ideal for interacting with Windows PCs on your network, or for generic appliances such as media streaming boxes.
First we install Samba:
[root@zeus ~]# yum install samba
Before we configure Samba, you need to think about who is going to need access to this. For an enterprise solution, clearly you’ll need some fancy authentication backend. For a home situation, it’s easier to set up a handful of users on your local system. Let’s assume you want to set up access for your wife, Sue.
[root@zeus ~]# useradd sue
[root@zeus ~]# passwd sue
So now Sue is set up on the server and has a password. Now we need to tell Samba that it’s OK to let system users get access to files. Open the file /etc/samba/smbusers. It should already have a couple of entries in, but you will need to add one for each user you want to use the file shares.
We back up and open the Samba config file for editing:
[root@zeus ~]# cp /etc/samba/smb.conf /etc/samba/smb.conf.old
[root@zeus ~]# vim /etc/samba/smb.conf
Delete all the contents of smb.conf. For now just add the contents of the global section below, but don’t close your editor yet – we need to define the shares.
[global]
dns proxy = no
log file = /var/log/samba/%m.log
cups options = raw
server string = Samba Server
socket options = TCP_NODELAY IPTOS_THROUGHPUT
username map = /etc/samba/smbusers
hosts allow = 192.168.0. 127.
max log size = 50
Now for some examples of how to define shares. The homes example automatically connects each user to their home directory, e.g. /home/sue. If you want this, keep it. If you don’t use your Linux home directories, don’t bother adding this section.
[homes]
comment = Home Directories
browseable = no
writeable = yes
This next one is an example of a media share for a TV streaming box or similar. All users can read it; only sue can write to it.
[media]
path = /media/public
writeable = yes
public = yes
write list = sue
This one is a private share only accessible by sue
This guide will attempt to show you how to build your own home server. I’ve included sections that I believe would be useful to home users, without over-complicating things. I’ve tried to make this guide accessible enough for people who are new to Linux, too.
We will assume that the core function of this server will be a gateway/firewall/router for your home network. If this is what you want, read on. However, if you wanted to build just a regular web/file/etc server, don’t follow this guide – it only works if the server is acting as a gateway for your LAN.
The goal of building a gateway/firewall/router relies upon a handful of other functions, such as DHCP and DNS. At the end of this article, there are also several optional extra features that you can add later.
Hardware
So, you’ve decided to build a home Linux server. What hardware do you need? Well, let’s look at each type of resource in turn:
Processor
Literally any processor will do for most applications. Even if you’re using your Internet connection heavily, the CPU will not be pushed at all. The only task in the list above that will even begin to push your CPU might be running some sort of PHP website.
Memory
Again, for a simple home server you don’t need a lot of RAM. My fully loaded server at home is currently using 309MB of its memory. For a basic server setup you could get away with 256MB but I’d recommend 512MB or more if you’re going to run a web server. The more you have, the better, as Linux will use it for caching frequently used files.
Disks/storage
A fully loaded CentOS server will probably need less than 3GB of disk space. As memory cards are so cheap these days, you could install to a CompactFlash card for a quieter server. The only thing that might take up space is a large website, or if youdecide to run a file server.
Network
Any old network connection will do for the Internet-facing side of your server. Whatever you have, it’ll be faster than your broadband/cable connection. The important network connection is the one that serves your private network. If you’re running a file server you might prefer to have a gigabit ethernet connection.
So now you know that a Linux home server doesn’t really need a lot of welly. It’s an ideal use for an old/spare desktop PC. The main problem with using an old PC is that they are noisy, and ineffecient at using power. Most older desktop PCs use around 100W. Very, very roughly, 1W for one year comes to around £1. So that’s £100/year running costs!
Depending on your house and the server’s location, the noise of an old PC might get on your nerves. It certainly does in my house. You might like to think about using a laptop (with an additional USB network adapter) or even something smaller and quiet like a Mac Mini or an EeeBox. According to Google, a Mac Mini only uses about 23W, too.
Choosing the OS
All Linux distributions are not equal. They vary greatly and it’s impossible to say that one is “better” than another. In this guide, I will be writing about building a server that runs CentOS. CentOS is a clone of Red Hat so the instructions should work on that too, as well as the closely-related Fedora. If you’re new to Linux, my advice would be to try CentOS unless you have a reason for installing something else.
Installing the OS
This is pretty straightforward on most modern Linux distributions. Just download and burn the CD or DVD, boot from it in your new server, and follow the instructions. If your server doesn’t have a CD drive, some distributions provide images designed to boot from a USB flash disk.
The most important thing to add here is that you should install the bare minimum of packages. Untick the boxes for everything – we will add what we need later.
Don’t forget the root password that you set – you’ll need that in a minute. After the installer has done its magic, wait for the server to restart and log on using the root username and password.
Setting up your network
Before we can get much further, the new server needs an Internet connection. If you have an existing home network, plug it into that. This guide assumes that you have a cable modem with an Ethernet connection into the server.
The basic network setup
This diagrams shows the basic layout of your network. The modem plugs into the server’s Ethernet port. On CentOS and related distributions, Ethernet ports are known by the system as eth0, eth1 and so on. You need to find out which port is which on your server. The best way of doing this is to simply plug the modem into whichever port takes your fancy. Assuming you already logged onto your server, simply type ipconfig at the terminal, as shown below:
If you have two Ethernet adapters, there will be entries for eth0 and eth1. One of them should have an “inet addr”, also known as an IP address. This one is then your Internet-facing network adapter. Make a note of it! Throughout the rest of this guide, I assume that eth0 faces the private network and eth1 faces the Internet.
Just to make sure that everything is alive on your server, test the connection:
[root@zeus ~]# ping -c4 www.google.com
PING www.l.google.com (209.85.229.147) 56(84) bytes of data.
64 bytes from ww-in-f147.google.com (209.85.229.147): icmp_seq=1 ttl=244 time=27.2 ms
64 bytes from ww-in-f147.google.com (209.85.229.147): icmp_seq=2 ttl=244 time=26.5 ms
64 bytes from ww-in-f147.google.com (209.85.229.147): icmp_seq=3 ttl=244 time=26.8 ms
64 bytes from ww-in-f147.google.com (209.85.229.147): icmp_seq=4 ttl=244 time=27.3 ms
--- www.l.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 4030ms
rtt min/avg/max/mdev = 26.516/26.920/27.331/0.332 ms
If you get 4 responses, all is well. If not, go back and fix it. Yep, it’s that kind of guide 😉 Now let’s move on to…
Setting up the basics
First things first, we need to update the packages that were installing when you installed CentOS from the CD.
[root@zeus ~]# yum -y update
This could take some time, so just let yum work its magic. After this, we need to install a few more packages to perform core functions.
Now we need to set up the other network connection – the one that serves your private LAN. For this we will use the private range of IP addresses – the ones that start 192.168.x.y.
For the first time since building the server, you need to use a text editor. I use vim but nano is a good one for beginners. Google for comparisons of various editors if you’re not sure. We need to edit the file the controls the private network connection. Double-check that you’ve chosen the right eth before you type this command:
[root@zeus ~]# vim /etc/sysconfig/networking/devices/ifcfg-eth0
There are a few entries in this file that must be changed – but there are also some that must be kept the same. Set the following ones to these values:
Don’t change DEVICE, HWADDR, or TYPE. Anything else can be safely deleted. Save your changes when you’re happy. To make this change take effect, type
[root@zeus ~]# service network restart
Just to make sure it worked, try ipconfig again and make sure that eth0 has an IP address of 192.168.0.1 and eth1 has some random other IP address.
Routing & Firewall
The routing (sending traffic to the right place, either inbound or outbound) and firewalling (filtering traffic) are controlled by iptables. First we need to enable the ability to route traffic between the two network interfaces:
Now for the tricky part. Writing an iptables config that protects the server while allowing the Internet through to the computers on your network. I will include a basic config here which should be enough to get you going. It allows all computers on your network to access the Internet, but does not allow unsolicited incoming traffic. It also open up your server to run as a web server. If this isn’t what you want, delete the two lines that mention 80 and 443 from the tcp_wan_inbound section. If you want to customise it a little, try playing with the Easy Firewall Generator for iptables.
If you use this exemplar config, open the file /etc/sysconfig/iptables for editing. Delete all the contents, and replace them with the following.
*mangle
:PREROUTING ACCEPT [30:2184]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [219:28347]
:OUTPUT ACCEPT [21:2964]
:POSTROUTING ACCEPT [427:80322]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth1 -j MASQUERADE
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [4:912]
# DEFINE VARIOUS CHAINS
:bad_packets - [0:0]
:bad_tcp_packets - [0:0]
:icmp_packets - [0:0]
:tcp_lan_inbound - [0:0]
:tcp_wan_inbound - [0:0]
:tcp_outbound - [0:0]
:udp_lan_inbound - [0:0]
:udp_wan_inbound - [0:0]
:udp_outbound - [0:0]
:syn_flood - [0:0]
# ALLOCATE TRAFFIC TO CHAINS
-A INPUT -i lo -j ACCEPT
-A INPUT -j bad_packets
-A INPUT -d 224.0.0.1 -j DROP
-A INPUT -s 192.168.0.0/255.255.255.0 -i eth0 -j ACCEPT
-A INPUT -d 192.168.0.255 -i eth0 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --sport 68 --dport 67 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -j tcp_lan_inbound
-A INPUT -i eth1 -p tcp -j tcp_wan_inbound
-A INPUT -i eth0 -p udp -j udp_lan_inbound
-A INPUT -i eth1 -p udp -j udp_wan_inbound
-A INPUT -i eth1 -p icmp -j icmp_packets
-A INPUT -i eth1 -p tcp --syn -j syn_flood
-A INPUT -m pkttype --pkt-type broadcast -j DROP
-A FORWARD -j bad_packets
-A FORWARD -i eth0 -p tcp -j tcp_outbound
-A FORWARD -i eth0 -p udp -j udp_outbound
-A FORWARD -i eth0 -j ACCEPT
-A FORWARD -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -p icmp -m state --state INVALID -j DROP
-A OUTPUT -s 127.0.0.1 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -s 192.168.0.1 -j ACCEPT
-A OUTPUT -o eth0 -j ACCEPT
-A OUTPUT -o eth1 -j ACCEPT
-A bad_packets -s 192.168.0.0/255.255.255.0 -i eth1 -j DROP
-A bad_packets -m state --state INVALID -j DROP
-A bad_packets -p tcp -j bad_tcp_packets
-A bad_packets -j RETURN
-A bad_tcp_packets -i eth0 -p tcp -j RETURN
-A bad_tcp_packets -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK,URG -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A bad_tcp_packets -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A bad_tcp_packets -p tcp -j RETURN
-A icmp_packets -p icmp -f -j DROP
-A icmp_packets -p icmp -m limit --limit 2/s --limit-burst 5 -j ACCEPT
-A icmp_packets -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A icmp_packets -p icmp -j RETURN
-A tcp_wan_inbound -p tcp -m tcp --dport 80 -j ACCEPT
-A tcp_wan_inbound -p tcp -m tcp --dport 443 -j ACCEPT
-A tcp_wan_inbound -i eth1 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A tcp_wan_inbound -i eth1 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP
-A tcp_wan_inbound -p tcp -m tcp --dport 22 -j ACCEPT
-A tcp_wan_inbound -p tcp -j RETURN
-A tcp_outbound -p tcp -j ACCEPT
-A udp_lan_inbound -p udp -j RETURN
-A udp_wan_inbound -p udp -m udp --dport 137 -j DROP
-A udp_wan_inbound -p udp -m udp --dport 138 -j DROP
-A udp_wan_inbound -p udp -j RETURN
-A udp_outbound -p udp -j ACCEPT
-A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN
-A syn_flood -j DROP
COMMIT
After you’re done inserting the firewall rules, you must apply them:
[root@zeus ~]# service iptables restart
DHCP
Let’s move on to setting up DHCP. This is a service that dynamically allocates IP addresses to other computers on your network, so they will automatically work when you connect them. Open dhcpd.conf in your editor:
Save it, close it, and let’s start the DHCP service.
[root@zeus ~]# service dhcpd start
Assuming that all goes OK, we also need to tell DHCP to start every time you turn the server on:
[root@zeus ~]# chkconfig --level 2345 dhcpd on
DNS
Now we come to set up DNS, so the clients on your network can look up domain names (e.g. google.com) and resolve them to IP addresses (e.g. 209.85.227.147).
The config here sets up your server as a DNS caching forwarder. Every time a computer on your network looks up a domain name, the server asks the upstream DNS servers (provided by your ISP), forwards the reply to the client and remembers the answer so next time a different client asks for the same domain name, the server can respond without wasting time by referring to the upstream DNS servers.
So first, you need to know the IP address(es) of the DNS servers provided by your ISP. As your server is already online and working, it should already know at least one DNS server, and you can make it tell you like this:
There may be one or more nameservers (DNS servers), and there may be other lines too. But all we want for now is to write down the IP addresses of all the DNS servers. We back up and edit the DNS config file to set these options:
[root@zeus ~]# cp /var/named/chroot/etc/named.conf /var/named/chroot/etc/named.conf.old
[root@zeus ~]# vim /var/named/chroot/etc/named.conf
Make it look like this, replacing my fictitious 1.1.1.1 and 2.2.2.2 with the IP addresses of your own DNS servers.
When you are done, restart the service and set it to start on boot:
[root@zeus ~]# service named restart
[root@zeus ~]# chkconfig --level 2345 named on
Optional steps
So, now you should find that you are able to simply connect a computer to your private network and it should pick up an IP address and all the details of your DNS system and just work automatically on the Internet. It’s worth restarting your server too, just to make sure it starts all of the services when it loads up (otherwise you’ll wonder why there’s no Internet after a power cut!).
I have also written some guides for setting up other, more advanced features for your home server, including:
This guide is particularly aimed at novice owners of Linux servers at home, such as the one described in a guide on this blog.
A transparent web proxy caches web content without having to make any changes on the clients on the network. For a proxy to run transparently, it must be running on a Linux server that’s acting as your network gateway/firewall/router. If you have a standalone server on your LAN, you can still set up a non-transparent proxy, but this guide isn’t for you.
To get started, install squid:
[root@zeus ~]# yum install squid
Backup and edit the original squid config:
[root@zeus ~]# cp /etc/squid/squid.conf /etc/squid/squid.conf.old
[root@zeus ~]# vim /etc/squid/squid.conf
Erase all of the original contents and replace them with the blurb below.
The important lines are in bold, and in my case:
I’ve asked squid to use 50MB of RAM for the cache…
…and 4096MB (4GB) of disk space. You can change the path if you want to use a different disk or even a memory card for low seek time.
I also increased the maximum object size from its default small size to a larger size of 40MB. (This is so it can cache updates from the Fedora repository – after the first PC on my LAN has updated, the rest can then fetch the same updates from the local cache at high speed.)
With the squid config in place, let’s start the service and set it to run on boot:
[root@zeus ~]# service squid start
[root@zeus ~]# chkconfig --level 2345 squid on
This is only half the problem though. Squid is running now, but no requests are being sent to it. So we need to tweak the firewall config to send passing web traffic through the squid server. Open /etc/sysconfig/iptables for editing and just before the line
For those of you who read my earlier post, Ubuntu Netbook Remix on an EeePC 701, you’ll know that I installed Ubuntu Netbook Remix (UNR) on my other half’s EeePC 701. The clue is very much in the name.
Initially I was sceptical of using it myself. I’m a Red Hat / CentOS / Fedora fan. All my home machines are Fedora; my work PC is Fedora and all the servers I look after are CentOS. My own EeePC 901 was, until yesterday, running Fedora too. I had no real gripes about Fedora on my 901, except the boot time, which was acceptable but slightly slow.
But after seeing how well thought-out UNR is, I was tempted to give it a shot. Despite being a Red Hat fan, I eventually decided that I didn’t actually use my 901 for anything Red Hat specific – basically I use it as a web browser, email client, MSN/AIM client and ssh terminal. So I’m not tied to any particular OS at all.
Installation from a Live USB was a breeze. My 901 has a so-called 20GB SSD, which is actually a 4GB SSD and a 16GB SSD. I’ve also added a 16GB SDHC card. In the end I set up my partitioning like:
4GB SSD: /var
16GB SSD: /boot, /
16GB SDHC: /home
In short, this gives me 16GB for the OS, and 16GB for my stuff. This is a pretty healthy amount for a netbook, and more than I’m likely to use in a hurry.
So what are my first thoughts on this Debian-based OS that I’m supposed to hate?
Well, it’s pretty good. The first thing I notice is how polished everything is. The login screen, the custom menu, the theme… UNR looks like a saleable OS. The UNR custom menu looks smart and is easy to use on a netbook screen – 9″ in my case, and 7″ in Hana’s.
I was able to configure my installation the way I like it without using a terminal. Of course, the terminal is there if I want it but I think this distro marks a new era – a Linux distribution that can be installed, configured and used without the user having to use the terminal. I’ve already said that my non-geek girlfriend Hana is using UNR and finds it great. I’d also be happy to recommend it to other non-technical users.
Bank holiday weekend finds me mooching around in my parents’ garden in the evening. This old goal net has seen better days, but I loved playing with it as a kid.
For anyone who also reads my photo blog, you might have seen that I went out around sunset last night to see if there were any interesting photos to be taken.
Before I left the house, I checked the official time of sunset on the BBC Weather website, and found it to be 9:04pm. I wasn’t really sure how “sunset” is defined, so I left the house early to cover myself.
My observations on the evening didn’t really help me deduce what is meant by “sunset” as it’s hard to tell when the sun goes below the horizon when there’s a gorge, some cliffs and a tall forest in the vicinity. I also wasn’t sure if it was the time that the leading edge, trailing edge, or midpoint of the sun touched the horizon. So I looked it up on Wikipedia.
In astronomy the time of sunset is defined as the moment the trailing edge of the sun’s disk disappears below the horizon in the west. Due to refraction of light in the atmosphere, the ray path of the setting sun is highly distorted near the horizon making the apparent astronomical sunset occur when the sun’s disk is already about one diameter below the horizon. Sunset should not be confused with dusk, which is the moment at which darkness falls, when the sun is about eighteen degrees below the horizon. The period between the astronomical sunset and dusk is called twilight.
So now you know. The official time is not only defined in a vague way (what’s the horizon?) but also hard to measure.
Last night I went for a walk around the Clifton downs and suspension bridge around sunset. The BBC forecast sunset at 9:04pm, and here’s what I came up with.
In the first picture, the sun was above the horizon but the light was lovely and golden, and allowed me to take this picture of the bridge.
8:44pm – Clifton Suspension Bridge
I got bored of taking pictures of the bridge, because it’s hard to take pictures of something very large if you’re also standing on it. So I walked up onto the hill where Clifton Observatory stands and took this picture – still in relatively bright light.
Clifton Suspension Bridge
Finally this last shot was taken a bit further down the downs, but not as far as the ice cream van (for those of you who know Bristol). I’m looking away from the bridge, down to Avonmouth. It is now well gone the official time of sunset, but still light enough to take photos.
I disagree. I say Bristol’s hardened urban cyclists are the silent killers. I am one of these cyclists, and I’ve had a couple of spills over the last few years.
But last week I was walking through the University part of the city and I noticed several cyclists doing really crazy things. Some were endangering others – some were endangering themselves. It’s remarkable how there aren’t more accidents involving cyclists.
So next time you’re out and about in an urban areas, don’t forget to use your eyes before you step into a road!