Linux Home NetworkingAuthor: Michael Minn (see michaelminn.com for contact info) 12 July 2011 A brief introduction of hardware and techniques for networking Linux computers in a home environment 1. IntroductionFrom it's origins, the UNIX operating system has been oriented around networking and UNIX machines are generally very easy to network and use on networks. Networking is a huge topic, but the following page contains some basic information that should be helpful for configuring modest home and small business networks. Basic information is also provided for connecting your Linux box to a network associated with a larger institution (such as a university). Although a number of graphical user interfaces are available for network configuration, use of software that shields the user from the technical workings of their system can sometimes be counterproductive. In a Linux environment where hardware and drivers are not specifically designed for the plethora of configurations, understanding the details of how a system is configured can be extremely helpful for diagnosing problems and actually save time. With that premise in mind, all configuration in this document is performed by editing system files or using command line programs. This document usually assumes a Ubuntu 8.04, although the commands will usually be valid on other Linux distributions. This document is not intended to be complete and I welcome any suggestions for it's improvement. 2. HardwarePerhaps the biggest issue facing a Linux user is finding hardware that is supported by vendor or open source drivers. Many manufacturers guard information about their hardware as trade secrets and see no need to expend effort on developing drivers for a rather small group of Linux users. Research: However, there are numerous vendors and projects that fill some of the holes. It is therefore ESSENTIAL that before purchasing hardware that you check the hardware compatibility lists AND Google your hardware to verify that drivers are available. The following are some online resources, although they are usually behind the curve and search engines will find up-to-date information.
Hardware Versions: Hardware vendors often change chipsetss while keeping the same model number. This means that two cards with the same model number can actually be completely different hardware, and Linux drivers for the old model may not work for the new version. Linux drivers often trail introduction of a product by months, by which time the vendor may have moved on to yet another chip vendor. Thankfully, many vendors issue the new hardware with a different "version" number that can be used to distinguish different releases of the same hardware. Product or serial numbers can also be used to distinguish new versions. BUYER BEWARE. Some information for specific hardware (current at the time of this writing) are given later in this document. Network Card: Every device on the network needs a network interface of some kind. Most new desktop and laptop computers have Ethernet ports (RJ-45 connectors) and modem ports (RJ-11 or phone line connectors), although the chips driving them may not have Linux drivers. Wireless and wired cards are available as internal cards (for desktops) or PCMCIA or USB devices. Again, do your research before buying. Switches/Routers: Once you have machines with network cards, you need some way to connect them. For a small number of machines, consumer-quality switches are usually simpler than routers. Routers are more complex and usually associated with a shared internet connection. Switches and routers often are mixed. There is a central router connected to the internet. Multiple machines in one room can be connected to a switch, which then has a single wire connected to the central router. Crossover Cables: If you are only connecting two machines, perhaps to share files between a laptop and a desktop, all you need is a crossover cable to connect them. Although this cable appears identical to a regular Ethernet cable, the connectors are wired so the outputs of one machine go to the inputs of the other. Access Points: For wireless networks, you need one or more access point to serve as a router between machines and between the network and an internet connection. It is possible for wireless machines to connect directly to each other (ad-hoc mode), although most networks centralize control (and internet access) through access points. Modems: Modems are used to connect to a remote machine (such as your internet service provider) through a phone line (dial-up or DSL) or cable connection. 4. Single Computer With a DSL or Cable ModemIf you have a single computer and a single high-speed Internet connection, setup is probably described by your ISP. Most common contemporary Linux distributions have daemons that detect Ethernet connections and automatically activate the network interfaces. However, it is possible to manually configure, start and stop interfaces without the aid of mysterious background processes. Device NamesAn internal, PCMCIA or USB networking device that has appropriate supporting modules installed on a machine will be recognized at boot or by hotplugging when the device plugged into the machine. Ethernet devices recieve the name ethX, where X is a number assigned by the sequence in which the device is detected. The first device is eth0, second device eth1, etc. Configuration files for Fedora distributions are located in /etc/sysconfig/network-scripts. They are named ifcfg-XXXX, where XXXX is the name of the device. For example, my /etc/sysconfig/network/ifcfg-eth0 file for an internal card connected to a DSL modem that is started at boot time. The DSL modem has DHCP, which assigns my interface an IP address: DEVICE=eth0 ONBOOT=yes BOOTPROTO=dhcp For a statically configured IP address on an interface that must be started manually: DEVICE=eth0 ONBOOT=no BOOTPROTO=static IPADDR=192.168.1.1 NETMASK=255.255.255.0 Debian/Ubuntu distributions have a single network interface configuration file, /etc/network/interfaces. Interfaces are configured with a single line. For example, my internal network card eth0, connected to a DSL modem and getting its IP address from DHCP on the modem: iface eth0 inet dhcp Interfaces can be manually started with the ifup and ifdown commands (run with superuser authority): sudo ifup eth0 5. A Two Computer Network with NFSIf you just need to share or transfer files between two systems, you can set up a simple network using a crossover cable or switch. Install NFS: Files under Network File System (NFS) are served by a server and accessed by a client. If you want to provide mutual access to files between two machines you will need to set both machines up as NFS servers and clients. If only one machine is being used for file storage, you only need NFS server on the source machine and the NFS client software on the other machine. Ubuntu distributions install the NFS server (unfs3 was formerly called nfs-user-server) with: sudo apt-get install portmap unfs3 The NFS client software is installed with: sudo apt-get install nfs-common Crossover Cable: For hardware, each computer needs an Ethernet card (10/100BaseT) and an RJ-45 CROSSOVER cable. Note that this is a crossover cable and not just a regular CAT-5 patch cable. Unless you're using a hub, the wires in the cable have to be "crossed over" to directly connect two PCs. Just plug one cable into the network port of one machine and plug the other end into the other machine. Switch: Optionally, if you wish to share file systems AND an Internet connection, you can interconnect machines by plugging regular Ethernet cables from each machine and the modem into a switch. Consumer grade switches are inexpensive and readily available anywhere computers are sold. IP Addresses: You will need to configure a static IP address on any machine that is configured as a server. The easiest choice is to use the Class C addresses 192.168.1.1 and 192.168.1.2 on the two machines, respectively. On a console on the source machine (the one with the files to be transferred), type: sudo ifconfig eth0 192.168.1.1 On the other machine: sudo ifconfig eth0 192.168.1.2 If you are planning on a permanent network, you will want to change the network configuration files to use these static IP addresses at all times, since IP addresses can vary when using DHCP. Network interface static IP address configuration is described in the previous section. If you also want to connect the server to the Internet through a DSL or able modem, you will have figure out a way to get a consistent IP address supplied to your server by the modem's DHCP service - such as always booting the server first when the network is restarted. This can be an issue with cable modems that assign IP addresses unpredictably and I can offer no reasonable solution. NFS Exports: The /etc/exports file tells NFS which directories to make visible to network systems. To make the /home directory visible to all machines with the IP addresses given above, the /etc/exports file on both machines would have one line: /home 192.168.1.0/255.255.255.0(rw) Mount point: The network file system will be visible through a mount point, a directory that the file system will associate with the remote machine. You can put this anywhere and call it anything you want, but /mnt or /mount are common places. sudo mkdir /mnt/network /etc/fstab: To tell the Linux file system how to mount the network file system, edit the /etc/fstab file and add the following line on the 192.168.1.2 machine, pointing to the 192.168.1.1 machine. 192.168.1.1:/home /mnt/network nfs noauto,user,exec,soft,nfsvers=2 0 0 On the 192.168.1.1 machine, the address would be changed to point to the 192.168.1.2 machine. The options in fourth column indicate not to try to mount at boot time (noauto), to allow a regular user (not just superuser) to mount the drive (user) and to timeout rather than retrying indefinitely if there is a problem accessing the device (soft). The given mount point (/mnt/network) can be any directory you prefer. To avoid confusion about different versions of the NFS protocols, the explicit version option is given above (nfsvers=2) Start NFS: Start the NFS daemons on the server /etc/init.d/unfs3 restart Mount: Network file systems just like physical drives: mount /mnt/network Network file systems can also be mounted explicitly (without an entry in the /etc/fstab file: mount -o nfsvers=2 192.168.1.1:/home /mnt/network You should now be able to see your remote directories under /mnt/network. Disabling NFS Start On Boot: If you are not planning on regularly accessing files via NFS, you should not leave the NFS server running and vulnerable to outside attacks. The startup scripts for NFS are in the /etc/rc* directories and you should rename them with the K prefix instead of the S prefix so they do not start at boot time: sudo rename s/S/K/ /etc/rc*/*nfs* 6. A Two Computer Network with NFS via WirelessA wireless connection can be used to interconnect two computers in place of an ethernet crossover cable. If you have a wireless router, the instructions above can be used with the addresses assigned by the router's DHCP server. If you don't have a wireless router, you can create an "Ad-Hoc" wireless network to interconnect the two machines. The following instructions should be executed on both machines to set the card into ad-hoc mode, specify a frequency, set the network name and set a WEP encryption key. Note that encryption keys specified as ASCII strings (s:) must be exactly 5 or 13 characters: sudo iwconfig wlan0 mode Ad-Hoc sudo iwconfig wlan0 channel 4 sudo iwconfig wlan0 essid omega sudo iwconfig wlan0 key s:alpha On the server machine, bring the interface up with the server address: sudo ifconfig wlan0 192.168.1.1 On the client machine, bring the interface up with the client address: sudo ifconfig wlan0 192.168.1.2 Attempt to ping the remote machine from the client to verify connectivity: ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=2.21 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.445 ms You should then be able to mount the remote filesystem on the client: mount 192.168.1.1:/home /mnt/network 7. NFS DebuggingNFS can be a MAJOR pain in the ass to get running, with cryptic error messages and strange freezes. The following are some errors I encountered and potential fixes. Some of these date from a previous experience with Fedora and they remain here for completeness. When all else fails, Google is your friend. Test the Connection: If mounting of an NFS file system is freezing or failing, you should first verify that you have connectivity to the server using ping. ping 192.168.1.1 Should give something like this: PING 192.168.1.1 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=0.895 ms 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.435 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.430 ms If you do not get ping messages, there's a problem with the basic connection between the machines. Verify that your cables are connected properly and firmly seated all the way into their sockets. If you are using a switch, make sure it is powered up and the indicator lights confirm connection. If you are using a crossover cable, make sure it is a crossover cable and not a regular Ethernet cable. NFS Version The Linux NFS client supposedly supports NFS protocol versions 2, 3, and 4 but the server doesn't seem quite so robust. nfsvers=2 is used above as the option on the mount command (or in /etc/fstab) to force use of NFS v2. If you fail to use explicit versioning, you may get a message like this: sudo mount -v 192.168.1.1:/home /mnt/network mount: no type was given - I'll assume nfs because of the colon mount.nfs: timeout set for Wed Dec 29 09:20:34 2010 mount.nfs: text-based options: 'addr=192.168.1.1' mount.nfs: mount(2): Protocol not supported mount.nfs: trying 192.168.1.1 prog 100003 vers 3 prot UDP port 2049 mount.nfs: mount to NFS server '192.168.1.1:/home' failed: RPC Error: Success By contrast, when you use explicit versioning: mount -o nfsvers=2 192.168.1.1:/home /mnt/network mount: no type was given - I'll assume nfs because of the colon mount.nfs: timeout set for Wed Dec 29 09:20:53 2010 mount.nfs: text-based options: 'nfsvers=2,addr=192.168.1.1' 192.168.1.1:/home on /mnt/network type nfs (rw,nfsvers=2) Access denied: This is likely caused because the directory you are trying to mount is not specified in /etc/exports on the NFS server. You should verify that file contains the correct info as described above. mount.nfs: access denied by server while mounting 192.168.1.1:/home RPC Error: Program not registered: This is likely caused because NFS or rpcbind is not running on the server. Execute "/etc/init.d/unfs3 start" on the server as described above. mount.nfs: mount to NFS server '192.168.1.1:/home' failed: RPC Error: Program not registered Server Is Down mount to NFS server 'x.x.x.x' failed: server is down This may, in fact, mean that the server is not running or that you do not have connectivity to the server (see above for ping). It can also be caused if the server does not have an entry in /etc/exports giving you permission to mount the requested resource (see above). However, this message may also be caused by a NFS protocol version mismatch. You should use NFS version 2 as described above. Permission denied on mount statd: Could not chdir: Permission denied mount.nfs: rpc.statd is not running but is required for remote locking. mount.nfs: Either use '-o nolock' to keep locks local, or start statd. This is a strange one. The easiest solution was to just mount as superuser: sudo mount /mnt/network However, subsequent mounts as non-superuser worked fine, so go figure. Starting NFS quotas: Cannot register service Starting NFS quotas: Cannot register service: RPC: Unable to receive; errno = Connection refused rpc.rquotad: unable to register (RQUOTAPROG, RQUOTAVERS, udp). This is a mysterious one. Seems to magically go away if you just restart NFS. /etc/init.d/unfs3 restart Firewall - iptables: If you are running a non-Ubuntu configuration or you have iptables running as a firewall, it needs to be configured to allow the client machine(s) to access NFS. On both machines, add a new iptables rule that accepts all input on the eth0 interface from the local network (both 192.168.1.1 and 192.168.1.2). List the new table and if everything looks good, save it to the /etc/sysconfig/iptables file. sudo iptables -I INPUT -p ALL -i eth0 -s 192.168.1.0/255.255.255.0 -j ACCEPT sudo iptables -L sudo iptables-save > /etc/sysconfig/iptables RPC: Port mapper failure - RPC: Unable to receive: NFS uses TCP/IP port 2049. The default firewalls on many distributions may cause mounting a drive on a remote machine to fail with the message: RPC: Port mapper failure - RPC: Unable to receive Solution is changing the iptable settings as described above. RPC: Timed out The firewall settings on the server or client may cause the mount to hang and eventually issue the message: RPC: Timed out Solution is changing the iptable settings as described above. Debugging - Ports: NFS uses TCP port 2049. rpcinfo can be used to list available ports. Problems with rpcinfo indicates a machine is not accepting NFS requests. rpcinfo You can also verify open ports with netstat. nfs should be listed for both tcp and udp, although only the tcp port will be in LISTEN state # netstat -tul Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:nfs *:* LISTEN tcp 0 0 *:printer *:* LISTEN tcp 0 0 *:676 *:* LISTEN tcp 0 0 *:sunrpc *:* LISTEN tcp 0 0 *:x11 *:* LISTEN tcp 0 0 *:ha-cluster *:* LISTEN tcp 0 0 *:32893 *:* LISTEN tcp 0 0 *:32894 *:* LISTEN udp 0 0 *:nfs *:* udp 0 0 *:32782 *:* udp 0 0 *:32783 *:* udp 0 0 *:673 *:* udp 0 0 *:691 *:* udp 0 0 *:bootpc *:* udp 0 0 *:727 *:* udp 0 0 *:sunrpc *:* iptables restart: If all else fails, you can simply stop the firewall. sudo service iptables stop If this solves the problem, you should look further into correcting your firewall configuration. Running without a firewall, especially with a connection to the internet exposes your machine to hacking and not recommended. FYI, an important line in /etc/sysconfig/iptables on some Red Hat configurations may be rejection of port 2049, used by NFS: -A RH-Lokkit-0-50-INPUT -p udp -m udp --dport 2049 -j REJECT 8. SambaThe Windoze operating system shares files through Server Message Blocks (SMB) and Network Message Blocks (NMB). Directories on a Windoze system that are made available for network access are called Shares. Samba is an open source package that provides file access between Windoze and Linux machines using SMB/NMB. Samba configuration is a huge topic, but some basic configuration information is given here for a simple home network. The utilities provided with Samba permit both access of Windoze shares from Linux systems and sharing of Linux directories with Windoze systems. useradd: Samba users from Windoze should have user accounts on the Linux machine. Usernames are added with the useradd command and passwords are set/changed with passwd. All users should have directories in /home as well. useradd (username) passwd (username) mkdir /home/(username) This can be combined into a single useradd request useradd -m -d /home/(username) -p (password) (username) smbpasswd: Samba keeps usernames and passwords in a separate file from regular Linux passwords. The smbpasswd command is uaed to add/delete Samba users. smbpasswd -a (username) /etc/samba/smb.conf: security: The type of access available for ALL samba shares are defined in the [global] section of /etc/samba/smb.conf. "share" security is read only, "user" security is read-write. [global] # read only access security = share # security = user /etc/samba/smb.conf: shares: Samba "shares" are configured in /etc/samba/smb.conf. To configure a share named (sharename), add the following section to the file:
[(sharename)]
comment = Shared directory named (sharename)
path = (filepath)
valid users = (username)
read only = No
Starting Samba Services: The rcnmb and rcsmb scripts start Samba filesharing and naming services: rcnmb start rcsmb start Mounting Samba Shares: Samba shares on other Linux or Windoze systems can be mounted just like other file systems and /etc/fstab can be used to define mount points and options. Example line in /etc/fstab: //(server)/(sharename) /(mountpoint) smb noauto,user,soft,ip=192.168.1.1,username=(user) 0 0 testparm: lists Samba shares and verifies correct syntax of configuration files smbstatus: a simple program to list currently open Samba connections. 10.2 Accessing Windoze Shares from LinuxIt is possible to access shares on a Windoze system from a Linux box either through smbclient (a program similar to FTP) or by mounting the shares as an SMB filesystem on Linux. The following examples presume unprotected shares. You may need additional workgroup/username/password information if the share is protected. Static IP Configuration: If you are using a crossover cable between your Windoze and Linux machines and have no DHCP server, you will need to configure a static IP address both machines. Sharing: Despite Windoze's notorious vulnerability to attack, getting a legitimate share visible to the world requires some confusing firewall configuration (including allowing exceptions) as well as actually configuring the folder to be shared. Find the IP address of the server: You should be able to get the IP address of the computer hosting the shares by simply viewing the network properties of the host. However, if you are in an unfamiliar environment, you can use NMAP to find valid IP addresses on a network. If the network is set up with DHCP, you can get the IP info for the network with ifconfig. Assuming a 192.168.0.0 network with a mask of 255.255.255.0 nmap -sP 192.168.0.0/24 List services on the computer: You can get the network name of the host computer by listing available services with nmblookup. Assuming the host computer IP is 192.168.0.1: nmblookup -A 192.168.0.1 List shares on a computer: Assuming that you found the 192.168.0.1 computer is named "mainserver", you can list the available shares with smbclient. Note that server names are normally preceded with "\\", but because the UNIX shell uses the slash as a special character, you use \\ to represent \\ UNLESS you put quotes around the whole name. smbclient -L \\\\mainserver -I 192.168.0.1 Connect to a share: If you only need to do simple transfer of files from/to the share, you can use the smbclient as a simple FTP-like program. Assuming a share named "sharedirectory" on computer "mainserver" with no password: smbclient \\\\mainserver\\sharedirectory "" -I 192.168.0.1 Like FTP, gets can only be of single files, not directories. However, if all you're doing is trying to get a whole directory of files off a Windoze machine, smbconnect has a "tar" command that permits recursive copies of complete directories from Windoze to Linux by creating tar archives. For example, to copy all files from a shared folder to the Linux machine: smbclient \\\\mainserver\\sharedirectory "" -Tc backup.tar . smbmount mounts a share so it can be accessed through the Linux filesystem. The findsmb and smbtree commands are available for viewing networks, although they requre additional configuration to work properly 9. DHCPDHCP (Dynamic Host Configuration Protocol) is a service provided by a server for assigning IP addresses to network hosts dynamically and eliminating the need to manually assign IP addresses to each computer on a network. The DHCP server needs a static IP address, but all hosts can have their network interface configurations set to get an IP address from the DHCP server. 11.1 DHCP ClientMost non-trivial networks, including networks that have access points or use routers to connect to the internet, have DHCP servers of some kind. A network card will get an address when the interface is brought up. Therefore dhcp must be specified in the config file for the particular interface. For a simple network card on eth0, the /etc/sysconfig/network-scripts/ifcfg-eth0 file will be: DEVICE=eth0 NAME=eth0 BOOTPROTO=dhcp ONBOOT=yes You can verify successful assignment of a dynamic IP address with ifconfig. You can also see diagnostic messages issued when seeking a DHCP address at the end of /var/log/messages DHCP addresses are "leased" for a set duration. There may be situations (such as DHCP server testing) where you need to relinquish a DHCP lease and acquire a new IP address. This can be done with dhclient. To release an IP address /sbin/dhclient -r To acquire a lease for one new IP address: /sbin/dhclient -1 11.2 DHCP Server/etc/sysconfig/dhcpd: Setup for a simple network is quite easy. Add an entry to /etc/syconfig/dhcpd for the network interface that will be be connected to hosts: DHCPD_INTERFACE="eth0" /etc/sysconfig/dhcpd.conf: Add a range of addresses that can be allocated to /etc/dhcpd.conf
ddns-update-style none;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.3 192.168.1.3;
}
iptables: Configure the firewall config file to permit incoming DHCP requests. (FYI: DHCP utilizes UDP on ports 67 and 68) /sbin/iptables -I INPUT -p ALL -i wlan0 -s 192.168.2.3 -j ACCEPT /sbin/iptables-save > /etc/sysconfig/iptables SuSE Firewall: If you're using SuSe, modify the following line in the /etc/sysconfig/SuSEfirewall2 file: FW_SERVICE_DHCPD="yes" Lease Info: Information about current DHCP leases is listed in /var/lib/dhcp/dhcpd.leases 10. Dialup AccessAlthough dialup access to the internet is rapidly going the way of buggy whips, millions of people still connect to the internet via analog phone lines. And travelers who stay in cheap hotels often find it necessary to get a dialup connection. Internal Modems: Finding a modem that works with Linux is actually a bit harder than it would seem. Most laptop and external modem designers have chosen to simplify their designs by moving some of the analog signal processing out of hardware and into the driver software. Since these drivers are almost never written for Linux, this presents a severe problem. However, there are a relatively small number of manufacturers making the chips used in these WinModems and, thankfully, SOME manufacturers and private developers have developed Linux drivers. Some resources for finding Linmodem info:
To know which driver to use, you need to know what chip the modem uses. This can be especially difficult on laptops or external devices where it is not easy to pop the case open and see the hardware. For internal modems, if you have Windoze installed, you can get the Properties of your LAN connection for detailed info. Lacking Windoze info, you may also be able to use the /sbin/lspci -vv command, although this may not be of value since dial-up modems are often hidden behind AC'97 chips, such as this listing from my Toshiba 1905 laptop: 00:1f.6 Modem: Intel Corp. 82801BA/BAM AC'97 Modem (rev 05) (prog-if 00 [Generic]) Subsystem: Toshiba America Info Systems: Unknown device 0001 Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR-Destination Gateway Genmask Flags Metric Ref Use Iface nas31.newyork1. * 255.255.255.255 UH 0 0 0 ppp0 default nas31.newyork1. 0.0.0.0 UG 0 0 0 ppp0 whois queries the Internet WhoIs database to find out who a domain name is registered to. Anonymous or third-world registrations often indicate entities that you should have no dealings with. whois can also be used to list to what organization an IP address has been assigned to, although this information will often only lead you to an ISP that controls a block of IP addresses and not to the company or individual who is actually using that IP address. airsnort: When you need to connect to an encrypted network but do not have the encryption key, AirSnort can listen to traffic for a period of time and determine the key. nmap is a network exporation tool and security scanner. Lots of options. The -sT option is especially useful for detecting "open ports" that represent potential entry paths for invaders and the results of this scan may indicate unnecessary services you want to shut down or unnecessary permissions in your firewall. Example: scan a local address for open ports nmap -sT 192.168.1.1 Example: looks for hosts on a network nmap -sP 172.16.1.1-127 Netdisco is an open source web-based network management tool. It's quite complex and I mention it here only as a suggestion if you're looking for network discovery software. nmblookup, smbstatus and findsmb are utilities for diagnosing and establishing Samba connections to Windoze systems. They are described earlier in this document. The solution to the energy problem is above our shoulders, not below our feet. |
All content on this site (c) 2000-2012 by Michael Minn or the respective copyright owners.