Windows file sharing on a Linux server

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.

# Unix_name = SMB_name1 SMB_name2 ...
root = administrator admin
nobody = guest pcguest smbguest
sue = sue
tvuser = tvuser

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

[private]
path = /media/private
writeable = yes
valid users = sue

After you’ve defined your shares, save the config, start the service and set it to run on boot

[root@zeus ~]# service smb start
[root@zeus ~]# chkconfig smb on

Building a Linux home server, gateway, firewall & router

Overview

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
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:


[root@zeus ~]# ifconfig
eth1      Link encap:Ethernet  HWaddr 00:19:5B:5D:21:B0
inet addr:84.x.y.z  Bcast:84.255.255.255  Mask:255.0.0.0
inet6 addr: fe80::219:5bff:fe5d:21b0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:17643164 errors:0 dropped:0 overruns:0 frame:0
TX packets:16261842 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:154049552 (146.9 MiB)  TX bytes:943414355 (899.7 MiB)
Interrupt:17 Base address:0xa000

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.

[root@zeus ~]# yum -y install bind bind-chroot dhcp hddtemp vim nano

Disable remote root login:

[root@zeus ~]# echo "PermitRootLogin no" >> /etc/ssh/sshd_config

I recommend you reboot after this:

[root@zeus ~]# init 6

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:


BOOTPROTO=none
IPADDR=192.168.0.1
ONBOOT=yes
NETMASK=255.255.255.0

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:

[root@zeus ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@zeus ~]# echo 1 > /proc/sys/net/ipv4/tcp_syncookies

And we also need to make sure this ability is switched on every time you start the server:

echo "echo 1 > /proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
echo "echo 1 > /proc/sys/net/ipv4/tcp_syncookies" >> /etc/rc.local

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:

[root@zeus ~]# vim /etc/dhcpd.conf

And make it look like this:

ddns-update-style interim;
ignore client-updates;
subnet 192.168.0.0 netmask 255.255.255.0 {
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.0.1;
option ip-forwarding off;
range dynamic-bootp 192.168.0.100 192.168.0.254;
default-lease-time 21600;
max-lease-time 43200;
}

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:

[root@zeus ~]# cat /etc/resolv.conf
nameserver 83.146.21.6
nameserver 212.158.249.5

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.

options {
listen-on port 53 { 192.168.0.1; 127.0/8; };
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-query { 192.168.0.0/24; 127.0/8; };
recursion yes;
forwarders { 1.1.1.1; 2.2.2.2; }; #IP of upstream ISP nameservers
forward only; #rely completely on our upstream nameservers
};

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:

Setting up squid as a transparent proxy

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.)

http_port 3128 transparent
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
acl localnet src 192.168.0.0/24 # RFC1918 possible internal network
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny to_localhost
http_access allow localhost
http_access allow localnet
http_access deny all
icp_access allow localnet
icp_access deny all
htcp_access allow localnet
htcp_access deny all
http_port 3128
hierarchy_stoplist cgi-bin ?
cache_mem 50 MB
maximum_object_size_in_memory 50 KB
cache_dir ufs /var/cache/squid 4096 256 256
maximum_object_size 40000 KB
access_log /var/log/squid/access.log squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern (cgi-bin|?) 0 0% 0
refresh_pattern . 0 20% 4320
icp_port 3130
coredump_dir /var/spool/squid

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

-A POSTROUTING -o eth1 -j MASQUERADE

add this line:

-A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Restart your firewall…

[root@zeus ~]# service iptables restart

…and now all web traffic from your clients should be being sent through the transparent proxy.

More on Ubuntu Netbook Remix

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.

Well done Ubuntu!

Sunset

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.

Sunset over Avon Gorge

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.

9:24pm – Avonmouth

Silent killer

They say carbon monoxide is the silent killer.

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!