|
|
|
Help, I've FallenCopyright © 1999 Gary Kline, David Leonard, and Dirk MyersThis issue of Help, I've Fallen welcomes the OpenBSD expertise of David Leonard who contributed to our last column.
Dirk and Gary have been Unix enthusiasts for a while now; both live in the Pacific Northwestern U.S.
How do I rebuild a new kernel for my *BSD machine?Each of the steps is simple by itself. With care and deliberation, everything should go smoothly. First, be certain that you have backed up you entire system before installing or the new kernel. It is a good idea that you do this periodically anyway. Let's assume that you are doing this for the first time and that the configuration files in CONF are untouched. cd to the directory which contains the kernel configuration files. If you're unsure of exactly what name your system is using to refer to <your-architecture>, use 'uname -m'. For example:
% uname -m
FreeBSD: /sys/<your-architecture>/conf NetBSD: /sys/arch/<your-architecture>/conf OpenBSD: /sys/arch/<your-architecture>/conf For all three flavors, the default kernel configuration file is called "GENERIC". The easiest way to set up a configuration file is to use the GENERIC file as a base. Copy the generic file to another filename. By convention, this file should be the name of your system. If your system is called thyme, then % cp GENERIC THYME If you want a configuration other than the GENERIC configuration, edit the file at this point. A complete rundown on all the changes you could possibly make to a kernel configuration would make for a long discussion, a possible future question for this column -- for now, we're going to assume that you want to rebuild the kernel with the default GENERIC file as a starting place. NetBSD and OpenBSD have a manual page describing the kernel config options: options(4). Now, use the 'config' program to set up a compilation directory, based on the settings you've specified in the configuration file. % config THYME This will create a directory with the same name as the config file. If a directory for this configuration already exists, config will update the existing directory. The location of the directory varies slightly by flavor: FreeBSD: /sys/<your-architecture>/compile/THYME NetBSD: /sys/arch/<your-architecture>/compile/THYME OpenBSD: /sys/arch/<your-architecutre>/compile/THYME cd to the directory config has just created. % cd ../compile/THYME Cautionary note: If you've built a kernel in this directory before, run a 'make clean' at this point. Create the dependencies with the make command: % make depend This will take anywhere from 'a few seconds' to 'a good, long time' depending on how fast your machine is. This command will also generate a lot of output which is highly dependent on *BSD flavor, your architecture, and your kernel configuration. Once the dependencies have been generated, you're ready to compile the kernel itself. Use the make command again, this time without arguments. % make Typically, a kernel build will take somewhat longer than generating dependencies does. Again, you'll see a lot of output. The new kernel file will appear in the compile directory. The actual name of the file is set by the "config" line in the config file. The default name varies slightly by *BSD flavor: FreeBSD: kernel NetBSD: netbsd OpenBSD: bsd Now, as root, move your old kernel. The name your system uses for the kernel is exactly the same as the defaults for new kernels above. For example, in FreeBSD: # mv /kernel /kernel.old The reason for doing this is that the boot loader will try the <kernel-name>.old file if the default kernel file doesn't work-- that is, is the new kernel loads and crashes, the most common scenario, the loader will choose <kernel-name>.old if <kernel-name> is deleted or corrupted. Now you are ready to move the kernel to the root directory. # cp kernel /kernel Last, but not least, you'll need to reboot your machine to use the new kernel. # reboot Because open source unix is an ever-moving target you will eventually find yourself with an outdated config file. i.e. GENERIC will evolve and the parts of THYME that came from GENERIC will no longer be in sync. Keeping THYME in sync with GENERIC is normally done by hand, since changes to GENERIC are infrequent and often small. One way to ease this process is to keep a copy of GENERIC (maybe called GENERIC.THYME) that is the same vintage as THYME. Whenever you feel the need to update THYME, you can use 'diff -u GENERIC.THYME GENERIC' to see what has changed. Don't forget to 'cp GENERIC GENERIC.THYME' after you have merged any needed changes into THYME. How do I set up my (fake-net) networked home computers to the (real) Internet?[ for FreeBSD | for NetBSD | for OpenBSD ]For FreeBSDThis used to be called ``IP-Masquarading'' since your pseudo- network needs to pretend to be a legit internet IP address. In the BSD realm you want natd a program that translates the network addresses of the ``real'' (internnet IP address) to your ``fake-net''. natd stands for the Network Address Translation Daemon, which, running in the background, intercepts and translates addresses transparently. natd has built-in firewalls hooks so that you can allow or deny whomever you wish from your private network. What follows is adapted with very few changes from the FreeBSD docs, so kudos and acknowledgements for a great job. Setting up NATD in FreeBSD The following steps are necessary before attempting to run natd: 1. Get FreeBSD version 2.2 or higher. Versions before this do not support divert(4) sockets. 2. Build a custom kernel with the following options: In your /usr/src/sys/i386/conf directory is your kernel configuration file, normally named what your system-name is named. The default name is GENERIC. In this file add: options IPFIREWALL options IPDIVERT In /sys/i386/conf, after you have added the two lines to your KERNEL configuration file, rebuild your kernel. If you have never rebuilt your kernel, see Question #1 above, rebuilding your kernel. ## above After rebuilding your kernel, edit /etc/rc.conf to enable your system to act as a gateway: gateway_enable=YES 3. If you wish to use natd's -n or -interface flags, make sure that your interface is already configured. If, for example, you wish to spec_ ify tun0 as your interface, and you're using ppp on that inter_ face, you must make sure that you start ppp prior to starting natd. For the purpose of this discussion, let's assume that your personal workstation is linked to the internet via a ppp connection through your ISP. And further, that your IP is dynamic. 4. Create an entry in /etc/services: natd 8668/divert # Network Address Translation socket This gives a default for the natd -p or -port flag. 5. You will need to adjust the /etc/rc.firewall script to taste. If you're not interested in having a firewall, the following lines will do: /sbin/ipfw -f flush /sbin/ipfw add divert natd all from any to any via tun0 /sbin/ipfw add pass all from any to any The second line depends on your interface (change tun0 as appropri_ ate) and assumes that you've updated /etc/services with the natd en_ try as above. If you specify real firewall rules, it's best to specify line 2 at the start of the script so that natd sees all packets before they are dropped by the firewall. The firewall rules will be run again on each packet after translation by natd, minus any divert rules. 6. Enable your firewall by setting firewall_enable=YES in /etc/rc.conf. This tells the system startup scripts to run the /etc/rc.firewall script. If you don't wish to reboot now, just run this by hand from the console. NEVER run this from a virtual session unless you put it into the background. If you do, your connection will be cut after the flush takes place, and execution of /etc/rc.firewall will stop at this point - blocking all network accesses. Running the script in the background should be enough to prevent this disaster. Running natd is fairly straight forward. The line natd <-interface> tun0 should suffice in most cases (substituting the correct interface name). 7. Edit /etc/rc.conf and make sure that this line is there, too, to enable packet forwarding. net.inet.ip.forwarding=1 and if avoiding rebooting, run the `sysctl' command as root: # sysctl -w net.inet.ip.forwarding=1 Running natd is fairly straight forward. The line natd <-interface> tun0 If you are running a 2.2 version of FreeBSD prior to 2.2.7, to start up natd, in your /etc/rc.local, put the following entry: echo "firing up natd" natd -use_sockets -same_ports -unregistered_only -interface tun0 If your IP is dynamic, add `-dynamic' to the <-interface> designation and natd will dynamically change the alias address. If you find this write-up on IP-aliasing clear and to the point it is due very largely the following authors' work, from which this section borrows heavily. The FreeBSD man page of natd ('man natd') has an even more in-depth discussion about this utility.
Setting up IPNAT in NetBSD or OpenBSDTo use IPNAT on NetBSD or OpenBSD, simply place the translation rules in the file /etc/ipnat.rules, and turn on 'ipf' and 'ipnat' in /etc/rc.conf. This will activate the IP packet filter (ipf) and IP network address translation (ipnat) functions in the kernel at the next reboot. Instead, you could start ipf and ipnat without rebooting, by running 'ipf -E' and 'ipnat -f /etc/ipnat.rules'. In both NetBSD and OpenBSD, the kernel options needed for IPNAT to work are turned on in GENERIC kernels. If you've compiled your own kernel, make sure you've got the following options turned on:
NetBSD
options INET # IP + ICMP + TCP + UDP
options PFIL_HOOKS # pfil(9) packet filter hooks
options IPFILTER_LOG # ipmon(8) support
...
pseudo-device ipfilter # IP filter (firewall) and NAT
OpenBSD
option INET # IP + ICMP + TCP + UDP
option IPFILTER # IP packet filter for security
option IPFILTER_LOG # use /dev/ipl to log ipf
Running IPNAT Once you've got IPNAT installed, you'll need to create a rule file. Here's a quick rundown on some sample rule files: Example 1. Dialing into an ISP from a machine at home. map ppp0 203.3.131.8/29 -> 0/32 portmap tcp/udp 10000:20000 map ppp0 203.3.131.8/29 -> 0/32 My dialout interface is always ppp0, and my home network's address is 203.3.131.8/29. So I wish to do translation 'at' interface ppp0, converting all outgoing 203.3.131.8/29 tcp and udp packets onto the outgoing interface's (dynamically assigned) IP address. I don't know the address ahead of time, so I specify 0/32 which is shorthand for 'this interface's address'. Example 2. Setting up a dial-in machine at work. map ed0 203.3.131.192/29 -> 0/32 portmap tcp/udp 10000:20000 map ed0 203.3.131.192/29 -> 0/32 This dial-in machine is connected to the LAN via ed0. When dialled in, routes are established to the private network 203.3.131.192/29 over ppp. We don't need to mention ppp, since translation occurs only at the ed0 interface. We wish to map outgoing packets at ed0 from the private network onto ed0's address (0/32 for short.) For further tricks (like using 'rdr' to redirect incoming traffic) and the meaning of the 10000:20000 port range, you are encouraged to read ipnat(1). Examples are provided on the system in the following directories: NetBSD: /usr/share/examples/ipf OpenBSD: /usr/share/ipf Some caveats Note that IPNAT only translates the packet *headers* as they pass through the interface. It does not translate IP addresses carried *within* the packet payload.
This means that these programs (among others) won't work through IPNAT:
Basically, anything that mentions your 'inside' IP address, and does not get translated, will cause grief. The correct way to fix this is to get and run protocol gateways (i.e. proxies). WARNING: IPNAT is not a firewall. It may mask the existence of IP addresses on the 'inside' of your network but cannot be reliably used to prevent network attacks in the same way that ipf can.
What are my backup options?Let's continue the discussion of backing up your files that we began in the December, 1998 column. Sooner or later, you're bound to lose some files, whether due to an accidental rm or a hard disk failure. If the data was worth the hours it took to create it is probably worth a few minutes safeguarding by having a backup. In the December issue we discussed several means of saving copies: by creating tape or floppy backups to using RCS to store versioned level. We'll begin with a brief discussion of dump and restore. If you want nightly backups and have a tape drive, you may find the dump(8) utility much more flexible than tar or rcp. Its companion program, restore, is an interactive program that allows you to search the dumps and recover your data. Both have the capability to work across the network. Following are some possible cron scripts using dump. #!/bin/sh /usr/bin/mt -f /dev/rst0 rewind /sbin/dump -0uBbf 4194304 32 /dev/nrst0 / /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /home /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /usr /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /usr2 /usr/bin/mt -f /dev/rst0 rewind #!/bin/sh /usr/bin/mt -f /dev/rst0 rewind /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /home /usr/bin/mt -f /dev/rst0 rewind #!/bin/sh /sbin/dump -0uBbf 4194304 32 /dev/nrst0 / # NO rewind /sbin/dump -0uBbf 4194304 32 /dev/rst0 /home # rewind #!/bin/sh /usr/bin/mt -f /dev/rst0 rewind /sbin/dump -0uBbf 4194304 32 /dev/nrst0 / /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /home #!/bin/sh /sbin/dump -0uBbf 4194304 32 /dev/nrst0 /usr # days later /usr/bin/mt -f /dev/rst0 rewind Since you will need to restore what you have dumped to tape, here are a few examples that use restore.
# restore -t # prints to stdout the contents of the whole tape
# restore -t XXX # prints to stdout the file `XXX' iff on the tape
# (format)
# inode <file> e.g.:
# 4581 ./XXX
# restore -x <filename filename2 filename3>
# restore -h <directory_name> restores entire directory.
# restore -i # gives you interactive capability.
% man restore
rdump and rrestore. For remote dumps and restore over any network you can access, the following two examples demonstrate the network versions. As you can see, the orthogonality is nearly one-to-one. The notable difference is, in rrestore where the -f <file> is one of "-f host:file" or "-f user@host:file". Here, "file" is /dev/rst0; but it could also be an ordinary filename, a disk drive (say, /dev/sd1s1a), or even stdin (-). rdump 0uBbf 2000000 10 thyme.thought.org:/dev/rst0 / rrestore -t -f thyme.thought.org:/dev/rst0 / It's also possible to back up tar files to a remote machine, or a drive attached to a remote machine. The trick here is to use 'rsh' (remote shell), which allows you to execute commands on a remote machine. The command executed is 'dd', which writes the data to a drive on the remote machine. (1) # tar -cf - / | rsh thyme.thought.org dd of=/dev/nrst0 (2) # tar -cvfb - 20 . | rsh thyme.thought.org dd=/dev/rst0 obs=20b It boils down to the following general syntax: (3) # tar -cf - <directory> | rsh <hostname> dd of=/dev/rst0 obs=20b The 'tar -cf - <directory>' command means to create an archive, of the directory, and write the archive to standard output. (Notice that rather than a filename after the 'f' flag, there's a '-'. This indicates standard output rather than an actual file). The archive is then piped to the dd command running on the remote machine. To restore files from a remote machine, you can use the following command: % rsh -n host thyme.thought.org dd if=/dev/rst0 bs=20b | tar -xvBfb - 20\ <list_of_files> In this case, the 'dd' command running on the remote host reads from the drive. The 'B' flag to tar forces tar to read from the pipe until blocks are entirely full. The 'f' flag is the everpresent 'file' flag. The 'b' flag indicates the block size which will be used. The parameter for the 'f' flag is the '-', which (in this context) means that tar should read from standard input. The parameter for the 'b' flag is 20, which indicates the block size for tar to read. Note that the '20' here matches the '20' for the block size specified in the dd command. I'm always running out of xterms because I have too many pseduo-ttys open. How can I increase my number of ptys?First, you'll need to set up your kernel to handle more pseudo-terminals. In the configuration file for your kernel (see the question above) change the line: pseudo-device pty 16 to: pseudo-device pty 128 (You can also use 32 or 64, if you don't need 128 pseudo-terminals.) Rebuild and reinstall your kernel, and reboot your machine. The kernel is now configured to handle up to 128 pseudo-devices. The next step is to create the device files that the system will use for each pseudo-terminal.As root, use the MAKEDEV script in the /dev directory to create the device files. As root. # cd /dev # ./MAKEDEV pty1 # ./MAKEDEV pty2 # ./MAKEDEV pty3 You will have created 128 pseudo-ttys. At this point, you should add entries for your new ttys to your /etc/ttys file. beneath the "# Pseudo terminals" column if they are not already listed. You will find at least ttyp0 through ttypv, and you need to edit in the rest. For this example, ttyq0 through ttyqv; ttyr0 through ttyrv; and ttys0 through ttysv. ttyq0 none network ttyq1 none network ttyq2 none network ttyq3 none network ttyq4 none network ttyq5 none network ttyq6 none network . . . ttysp none network ttysq none network ttysr none network ttyss none network ttyst none network ttysu none network ttysv none network Without the additional ptys in /etc/ttys you may run out of pseudo-ttys to use for rlogin and telnet. I just upgraded my system and now ps has quit working. How do I fix ps?Because the 'ps' program needs intimate knowledge of the kernel's most private data structures, it is important that is compiled at or about the same time as the kernel. If this isn't the case, it doesn't find what it expects in the kernel, and stops functioning. If your upgrade consisted solely of installing a new kernel, you will need to either download a new base distribution or recompile the system utilities that have stopped working. (In the latter case you will need the source code, and it is highly likely that you will need to re-build and install libkvm first.) If your upgrade involved installing a newer ps, but not a newer kernel, you will need to either download a new kernel image (with a date that is about the same as 'ps'), or rebuild your kernel with the newer sources. Look here for information on rebuilding your kernel. Tip of the monthIt's fairly obvious, even to new BSD users, to be extra-careful when doing anything as root. As obvious as it may seem to build-in extra caution into your /root/.cshrc, this is not yet a default. Adding the following alias will almost invariably save your hide -- or at least time in recovering files from your backup, sooner or later. If you are deleting entire directories or a great number of files, and you are certain that you wish to do this, it is a trivial amount of addition effort to type /bin/rm over simply rm
alias rm '/bin/rm -i \!*' This alias assumes that you are using the csh as your root shell. If you are using another shell, this must be modified accordingly. If you do much development work in your personal account this rm alias is a good idea there as well.
Gary Kline kline@tao.thought.org,
|
||