I already know this is "broken", but I'm trying to fix it. I have however, run into a brick wall. As requested, I'll attach all the relevant information below, but decided it was too distracting to have in the middle of the e-mail. I don't think you should need the hostname/ip address info, so I deleted it. Also note, though I have this coming from one of my personal e-mail addresses, this is for a project at work, I will be transitioning jobs, but may still want to work with ipfilter afterwards, so I figured I'd use my personal address. We use ipfilter on Solaris for a mostly Sun network, but recently some RHEL boxes have been added. One of our objective requirements would be to use a single firewall config for the machines, as most talk to one another, and the same outside hosts. Thus, if we can use ipfilter on RHEL, we can meet the objective requirement. Otherwise, we'll investigate an option to script a conversion from an ipf.conf and ippool.conf file into an iptables configuration (and still only maintain 1 config), or if all else fails, switch to just 2 seperate configs. We don't have a lot of time for this either (in fact, http://www.dilbert.com/2010-03-14/ was posted in a meeting we had about schedule :-) ) So here is what I have done. I started with ipfilter 4.1.33 and tried to compile it on an x86 CentOS 5.4 machine. I quickily ran into the problem of get_random_int no longer being exported. My solution? Copy the code into ipfilter since the functions it used were exported. This was trivial, with the only changes necessary being names, and having an unload routine to cancel the scheduled task. I'll post the patch at the end. It's not very robust as I did not investigate the kernel version that get_random_int acutally disappeared, but it will work for 2.6.18 kernel versions. Once finished, everything went great. I was able to enable ipfilter, I watched appropriate traffic get blocked, and passed. Seemed we were ready to burn it to a cd and took it down to the lab. Well, we got down there and found out they decided to use RHEL x86_64. D'Oh! So we got access to a more accessible RHEL 5.4 x86_64 machine, and built on there. Same patch, same no trouble compiling, and installing. Trouble occured when I enabled ipfilter. Suddenly all traffic was blocked. ipfstat showed nothing as being blocked or passed, but an rmmod ipfilter made everything work again. I'd start a ping and then do /etc/init.d/ipfilter start and the ping would stop, then /etc/init.d/ipfilter stop, and the pings would immediatly come back.
I'm pretty much at a loss. Everything worked fine on my CentOS 5.4 x86 machine, and nothing works on the RHEL 5.4 x86_64 machine. SELinux is Permissive on the CentOS machine, and Disabled on the RHEL machine, so that does not seem to be the problem. I have seen one other person on the list was working to get ipfilter running in RHEL 5.2 with some success. I did check, and saw what he had in the patch had been integrated into the source in 4.1.33, so unfortunatly that is not my issue. I could not find anything else even close to similar, so I decided I'd actually join the list and see what the community had to say about it! Right now, I am trying to figure out if it is a difference in the RHEL kernel vs the CentOS kernel (I thought they would be the same, but, I've not confirmed that fact), or if the problem lies in the x86 vs the x86_64 difference. Any leads/rabbit holes/etc would be appreciated, and any additional clarification will be given as necessary! [r...@hostnamedeleted ip_fil4.1.33_modified]# uname -a Linux hostnamedeleted 2.6.18-164.11.1.el5 #1 SMP Wed Jan 6 13:26:04 EST 2010 x86_64 x86_64 x86_64 GNU/Linux [r...@hostnamedeleted ip_fil4.1.33_modified]# isainfo -vk -bash: isainfo: command not found [r...@hostnamedeleted ip_fil4.1.33_modified]# ifconfig -a eth0 Link encap:Ethernet HWaddr 00:22:19:80:A5:54 inet addr:ip_addr_deleted Bcast:bcast_deleted Mask:255.255.255.0 inet6 addr: fe80::222:19ff:fe80:a554/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:28505 errors:0 dropped:0 overruns:0 frame:0 TX packets:3171 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2297833 (2.1 MiB) TX bytes:296497 (289.5 KiB) Interrupt:169 Memory:da000000-da012800 eth1 Link encap:Ethernet HWaddr 00:22:19:80:A5:56 inet addr:ip_addr_deleted Bcast:bcast_deleted Mask:255.255.255.0 inet6 addr: fe80::222:19ff:fe80:a556/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:30413 errors:0 dropped:0 overruns:0 frame:0 TX packets:17557 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:9095364 (8.6 MiB) TX bytes:4183335 (3.9 MiB) Interrupt:169 Memory:d6000000-d6012800 eth2 Link encap:Ethernet HWaddr 00:10:18:3D:0C:36 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) Interrupt:82 Memory:d2000000-d2012800 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:169175 errors:0 dropped:0 overruns:0 frame:0 TX packets:169175 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:71886254 (68.5 MiB) TX bytes:71886254 (68.5 MiB) sit0 Link encap:IPv6-in-IPv4 NOARP MTU:1480 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) [r...@hostnamedeleted ip_fil4.1.33_modified]# netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface eth1_ip_deleted 0.0.0.0 255.255.255.0 U 0 0 0 eth1 eth0_ip_deleted 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 0.0.0.0 eth1_gw_deleted 0.0.0.0 UG 0 0 0 eth1 [r...@hostnamedeleted ip_fil4.1.33_modified]# netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 28505 0 0 0 3171 0 0 0 BMRU eth1 1500 0 30413 0 0 0 17557 0 0 0 BMRU lo 16436 0 169175 0 0 0 169175 0 0 0 LRU [r...@hostnamedeleted ip_fil4.1.33_modified]# netstat -s --ip Ip: 200414 total packets received 83 with invalid addresses 0 forwarded 0 incoming packets discarded 199723 incoming packets delivered 194007 requests sent out 180 outgoing packets dropped Icmp: 409 ICMP messages received 115 input ICMP message failed. ICMP input histogram: destination unreachable: 341 echo requests: 34 echo replies: 34 473 ICMP messages sent 0 ICMP messages failed ICMP output histogram: destination unreachable: 341 echo request: 98 echo replies: 34 IcmpMsg: InType0: 34 InType3: 341 InType8: 34 OutType0: 34 OutType3: 341 OutType8: 98 Tcp: 1744 active connections openings 855 passive connection openings 713 failed connection attempts 68 connection resets received 32 connections established 193271 segments received 191106 segments send out 347 segments retransmited 0 bad segments received. 327 resets sent Udp: 1510 packets received 15 packets to unknown port received. 0 packet receive errors 1256 packets sent TcpExt: 6 invalid SYN cookies received 883 TCP sockets finished time wait in fast timer 16351 delayed acks sent 1 delayed acks further delayed because of locked socket 120209 packets directly queued to recvmsg prequeue. 36680 packets directly received from backlog 22487745 packets directly received from prequeue 12761 packets header predicted 112257 packets header predicted and directly queued to user 10074 acknowledgments not containing data received 126936 predicted acknowledgments 31 times recovered from packet loss due to SACK data 40 congestion windows recovered after partial ack 20 TCP data loss events 5 timeouts after SACK recovery 1 timeouts in loss state 33 fast retransmits 3 forward retransmits 32 retransmits in slow start 301 other TCP timeouts 2 sack retransmits failed 3 DSACKs sent for old packets 7 connections reset due to unexpected data 62 connections reset due to early user close 32 connections aborted due to timeout IpExt: InMcastPkts: 1138 OutMcastPkts: 520 InBcastPkts: 3730 [r...@hostnamedeleted ip_fil4.1.33_modified]# ipf -V ipf: IP Filter: v4.1.33 (496) open device: No such device or address [r...@hostnamedeleted ip_fil4.1.33_modified]# ipfstat open(IPSTATE_NAME): No such device or address [r...@hostnamedeleted ip_fil4.1.33_modified]# ipfstat -io open(IPSTATE_NAME): No such device or address [r...@hostnamedeleted ip_fil4.1.33_modified]# ipnat -slv /dev/ipnat: open: No such device or address I don't have ipfilter loaded, but I did save the output from ipfstat -io, which is currently pass in on any all pass out on any all after finding the more complicated ruleset with pools had loaded correctly, and I had no network access, I tried simplifying :) I'm not doing anything with ipnat, so I do not even have an ipnat.conf file. As stated, there are no pools either. uname -a on the CentOS machine is Linux GuardianLegend 2.6.18-164.11.1.el5PAE #1 SMP Wed Jan 20 08:16:13 EST 2010 i686 i686 i386 GNU/Linux I won't post the other information because it has the production firewall rules loaded on it, and a pools file with the production rules (different subnets though, but still). Everything there works though :) The patch I created to re-add get_random_int follows... diff -ruN ip_fil4.1.33/ip_compat.h ip_fil4.1.33_modified/ip_compat.h --- ip_fil4.1.33/ip_compat.h 2009-08-16 03:05:40.000000000 -0400 +++ ip_fil4.1.33_modified/ip_compat.h 2010-03-16 16:50:06.000000000 -0400 @@ -1273,13 +1273,20 @@ # define bcopy(s,d,z) memmove(d, s, z) # define bzero(s,z) memset(s, 0, z) # define bcmp(a,b,z) memcmp(a, b, z) + # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) # define ipf_random random32 # define arc4random random32 # else -# include <linux/random.h> -# define ipf_random get_random_int -# define arc4random get_random_int +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +# include "ip_gri.h" +# define ipf_random ipf_get_random_int +# define arc4random ipf_get_random_int +# else +# include <linux/random.h> +# define ipf_random get_random_int +# define arc4random get_random_int +# endif # endif # define ifnet net_device diff -ruN ip_fil4.1.33/ip_gri.c ip_fil4.1.33_modified/ip_gri.c --- ip_fil4.1.33/ip_gri.c 1969-12-31 19:00:00.000000000 -0500 +++ ip_fil4.1.33_modified/ip_gri.c 2010-03-16 19:07:54.000000000 -0400 @@ -0,0 +1,286 @@ +/* + * ip_gri.c -- A copy of a strong random number generator + * + * Copyright Matt Mackall <[email protected]>, 2003, 2004, 2005 + * + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All + * rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * (now, with legal B.S. out of the way.....) + * + * This routine gathers environmental noise from device drivers, etc., + * and returns good random numbers, suitable for cryptographic use. + * Besides the obvious cryptographic uses, these numbers are also good + * for seeding TCP sequence numbers, and other places where it is + * desirable to have numbers which are not only random, but hard to + * predict by an attacker. + * + * Theory of operation + * =================== + * + * Computers are very predictable devices. Hence it is extremely hard + * to produce truly random numbers on a computer --- as opposed to + * pseudo-random numbers, which can easily generated by using a + * algorithm. Unfortunately, it is very easy for attackers to guess + * the sequence of pseudo-random number generators, and for some + * applications this is not acceptable. So instead, we must try to + * gather "environmental noise" from the computer's environment, which + * must be hard for outside attackers to observe, and use that to + * generate random numbers. In a Unix environment, this is best done + * from inside the kernel. + * + * Sources of randomness from the environment include inter-keyboard + * timings, inter-interrupt timings from some interrupts, and other + * events which are both (a) non-deterministic and (b) hard for an + * outside observer to measure. Randomness from these sources are + * added to an "entropy pool", which is mixed using a CRC-like function. + * This is not cryptographically strong, but it is adequate assuming + * the randomness is not chosen maliciously, and it is fast enough that + * the overhead of doing it on every interrupt is very reasonable. + * As random bytes are mixed into the entropy pool, the routines keep + * an *estimate* of how many bits of randomness have been stored into + * the random number generator's internal state. + * + * When random bytes are desired, they are obtained by taking the SHA + * hash of the contents of the "entropy pool". The SHA hash avoids + * exposing the internal state of the entropy pool. It is believed to + * be computationally infeasible to derive any useful information + * about the input of SHA from its output. Even if it is possible to + * analyze SHA in some clever way, as long as the amount of data + * returned from the generator is less than the inherent entropy in + * the pool, the output data is totally unpredictable. For this + * reason, the routine decreases its internal estimate of how many + * bits of "true randomness" are contained in the entropy pool as it + * outputs random numbers. + * + * If this estimate goes to zero, the routine can still generate + * random numbers; however, an attacker may (at least in theory) be + * able to infer the future output of the generator from prior + * outputs. This requires successful cryptanalysis of SHA, which is + * not believed to be feasible, but there is a remote possibility. + * Nonetheless, these numbers should be useful for the vast majority + * of purposes. + * + * Acknowledgements: + * ================= + * + * Ideas for constructing this random number generator were derived + * from Pretty Good Privacy's random number generator, and from private + * discussions with Phil Karn. Colin Plumb provided a faster random + * number generator, which speed up the mixing function of the entropy + * pool, taken from PGPfone. Dale Worley has also contributed many + * useful ideas and suggestions to improve this driver. + * + * Any flaws in the design are solely my responsibility, and should + * not be attributed to the Phil, Colin, or any of authors of PGP. + * + * Further background information on this topic may be obtained from + * RFC 1750, "Randomness Recommendations for Security", by Donald + * Eastlake, Steve Crocker, and Jeff Schiller. + * + * As you may have guessed.... + * =========================== + * This is NOT in fact, a random driver. Instead, it is a bit of a copy of + * the random driver. Unfortunatly sometime ago, the linux kernel maintainers + * decided they did not need to export the get_random_int function, because + * to their knowlege, nobody was using it. Well, turns out ipfilter was! + * If we were operating on a kernel version >= 2.6.23, there would be no + * problem, however, it looks like the project I am currently working will be + * using 2.6.18. No good, no random32 function, and no get_random_int, so + * now what? Use a custom kernel on every machine, go through accredidation, + * and a ton of work, just to export a symbol? I'd rather not. So my option + * is to take a direct copy of the /driver/char/random get_random_int function + * and drop it in here. We have to build ipfilter from source anyway, so we + * already have the overhead of dealing with a non-binary source package. + * seems to be the easiest place to make the change! I traced through all the c * code and found no reason I can't just copy it into here and expect good + * results. I have changed the names to use ipf in some way to prevent name + * conflicts (since we do use get_random_bytes, means we need to include + * random.h, so there *WILL* be conflicts, and I figured I might as well + * protect the innocent while I was at it. + * Anyhow, here is the relevant code needed for get_random_int nearly verbatim. +*/ + +/* END OF INCLUDES */ + + + +#include <linux/utsname.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/major.h> +#include <linux/string.h> +#include <linux/fcntl.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/poll.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/genhd.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/percpu.h> +#include <linux/cryptohash.h> +#include <asm/processor.h> +#include <asm/uaccess.h> +#include <asm/irq.h> +#include <asm/io.h> + + + + +/* This should not be decreased so low that ISNs wrap too fast. */ +#define IPF_REKEY_INTERVAL (300 * HZ) +/* + * Bit layout of the tcp sequence numbers (before adding current time): + * bit 24-31: increased after every key exchange + * bit 0-23: hash(source,dest) + * + * The implementation is similar to the algorithm described + * in the Appendix of RFC 1185, except that + * - it uses a 1 MHz clock instead of a 250 kHz clock + * - it performs a rekey every 5 minutes, which is equivalent + * to a (source,dest) tulple dependent forward jump of the + * clock by 0..2^(HASH_BITS+1) + * + * Thus the average ISN wraparound time is 68 minutes instead of + * 4.55 hours. + * + * SMP cleanup and lock avoidance with poor man's RCU. + * Manfred Spraul <[email protected]> + * + */ +#define IPF_COUNT_BITS 8 +#define IPF_COUNT_MASK ((1 << IPF_COUNT_BITS) - 1) +#define IPF_HASH_BITS 24 +#define IPF_HASH_MASK ((1 << HASH_BITS) - 1) + + + +static struct ipfkeydata { + __u32 count; /* already shifted to the final position */ + __u32 secret[12]; +} ____cacheline_aligned ipf_keydata[2]; + +static unsigned int ipf_cnt; + +static void ipf_rekey_seq_generator(void *private_); + +static DECLARE_WORK(ipf_rekey_work, ipf_rekey_seq_generator, NULL); + +/* + * Lock avoidance: + * The ISN generation runs lockless - it's just a hash over random data. + * State changes happen every 5 minutes when the random key is replaced. + * Synchronization is performed by having two copies of the hash function + * state and ipf_rekey_seq_generator always updates the inactive copy. + * The copy is then activated by updating ipf_cnt. + * The implementation breaks down if someone blocks the thread + * that processes SYN requests for more than 5 minutes. Should never + * happen, and even if that happens only a not perfectly compliant + * ISN is generated, nothing fatal. + */ +static void ipf_rekey_seq_generator(void *private_) +{ + struct ipfkeydata *keyptr = &ipf_keydata[1 ^ (ipf_cnt & 1)]; + + get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); + keyptr->count = (ipf_cnt & IPF_COUNT_MASK) << IPF_HASH_BITS; + smp_wmb(); + ipf_cnt++; + schedule_delayed_work(&ipf_rekey_work, IPF_REKEY_INTERVAL); +} + +static inline struct ipfkeydata *get_ipfkeyptr(void) +{ + struct ipfkeydata *keyptr = &ipf_keydata[ipf_cnt & 1]; + + smp_rmb(); + + return keyptr; +} + +int ipf_seqgen_init(void) +{ + ipf_rekey_seq_generator(NULL); + return 0; +} +int ipf_seqgen_fini(void) +{ + cancel_rearming_delayed_work(&ipf_rekey_work); + return 0; +} +/* +late_initcall(ipf_seqgen_init); +*/ +/* The code and comment below is shamelessly stolen from secure_ip_id(). + * The code below is shamelessly stolen from secure_tcp_sequence_number(). + * All blames to Andrey V. Savochkin <[email protected]>. + */ +__u32 ipf_secure_ip_id(__u32 daddr) +{ + struct ipfkeydata *keyptr; + __u32 hash[4]; + + keyptr = get_ipfkeyptr(); + + /* + * Pick a unique starting offset for each IP destination. + * The dest ip address is placed in the starting vector, + * which is then hashed with random data. + */ + hash[0] = daddr; + hash[1] = keyptr->secret[9]; + hash[2] = keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return half_md4_transform(hash, keyptr->secret); +} + +unsigned int ipf_get_random_int(void) +{ + /* + * Use IP's RNG. It suits our purpose perfectly: it re-keys itself + * every second, from the entropy pool (and thus creates a limited + * drain on it), and uses halfMD4Transform within the second. We + * also mix it with jiffies and the PID: + */ + return ipf_secure_ip_id(current->pid + jiffies); +} + + + + diff -ruN ip_fil4.1.33/ip_gri.h ip_fil4.1.33_modified/ip_gri.h --- ip_fil4.1.33/ip_gri.h 1969-12-31 19:00:00.000000000 -0500 +++ ip_fil4.1.33_modified/ip_gri.h 2010-03-16 19:06:25.000000000 -0400 @@ -0,0 +1,148 @@ +/* + * ipf_gri.c -- A copy of a strong random number generator + * + * Copyright Matt Mackall <[email protected]>, 2003, 2004, 2005 + * + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All + * rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * (now, with legal B.S. out of the way.....) + * + * This routine gathers environmental noise from device drivers, etc., + * and returns good random numbers, suitable for cryptographic use. + * Besides the obvious cryptographic uses, these numbers are also good + * for seeding TCP sequence numbers, and other places where it is + * desirable to have numbers which are not only random, but hard to + * predict by an attacker. + * + * Theory of operation + * =================== + * + * Computers are very predictable devices. Hence it is extremely hard + * to produce truly random numbers on a computer --- as opposed to + * pseudo-random numbers, which can easily generated by using a + * algorithm. Unfortunately, it is very easy for attackers to guess + * the sequence of pseudo-random number generators, and for some + * applications this is not acceptable. So instead, we must try to + * gather "environmental noise" from the computer's environment, which + * must be hard for outside attackers to observe, and use that to + * generate random numbers. In a Unix environment, this is best done + * from inside the kernel. + * + * Sources of randomness from the environment include inter-keyboard + * timings, inter-interrupt timings from some interrupts, and other + * events which are both (a) non-deterministic and (b) hard for an + * outside observer to measure. Randomness from these sources are + * added to an "entropy pool", which is mixed using a CRC-like function. + * This is not cryptographically strong, but it is adequate assuming + * the randomness is not chosen maliciously, and it is fast enough that + * the overhead of doing it on every interrupt is very reasonable. + * As random bytes are mixed into the entropy pool, the routines keep + * an *estimate* of how many bits of randomness have been stored into + * the random number generator's internal state. + * + * When random bytes are desired, they are obtained by taking the SHA + * hash of the contents of the "entropy pool". The SHA hash avoids + * exposing the internal state of the entropy pool. It is believed to + * be computationally infeasible to derive any useful information + * about the input of SHA from its output. Even if it is possible to + * analyze SHA in some clever way, as long as the amount of data + * returned from the generator is less than the inherent entropy in + * the pool, the output data is totally unpredictable. For this + * reason, the routine decreases its internal estimate of how many + * bits of "true randomness" are contained in the entropy pool as it + * outputs random numbers. + * + * If this estimate goes to zero, the routine can still generate + * random numbers; however, an attacker may (at least in theory) be + * able to infer the future output of the generator from prior + * outputs. This requires successful cryptanalysis of SHA, which is + * not believed to be feasible, but there is a remote possibility. + * Nonetheless, these numbers should be useful for the vast majority + * of purposes. + * + * Acknowledgements: + * ================= + * + * Ideas for constructing this random number generator were derived + * from Pretty Good Privacy's random number generator, and from private + * discussions with Phil Karn. Colin Plumb provided a faster random + * number generator, which speed up the mixing function of the entropy + * pool, taken from PGPfone. Dale Worley has also contributed many + * useful ideas and suggestions to improve this driver. + * + * Any flaws in the design are solely my responsibility, and should + * not be attributed to the Phil, Colin, or any of authors of PGP. + * + * Further background information on this topic may be obtained from + * RFC 1750, "Randomness Recommendations for Security", by Donald + * Eastlake, Steve Crocker, and Jeff Schiller. + * + * As you may have guessed.... + * =========================== + * This is NOT in fact, a random driver. Instead, it is a bit of a copy of + * the random driver. Unfortunatly sometime ago, the linux kernel maintainers + * decided they did not need to export the get_random_int function, because + * to their knowlege, nobody was using it. Well, turns out ipfilter was! + * If we were operating on a kernel version >= 2.6.23, there would be no + * problem, however, it looks like the project I am currently working will be + * using 2.6.18. No good, no random32 function, and no get_random_int, so + * now what? Use a custom kernel on every machine, go through accredidation, + * and a ton of work, just to export a symbol? I'd rather not. So my option + * is to take a direct copy of the /driver/char/random get_random_int function + * and drop it in here. We have to build ipfilter from source anyway, so we + * already have the overhead of dealing with a non-binary source package. + * seems to be the easiest place to make the change! I traced through all the c * code and found no reason I can't just copy it into here and expect good + * results. I have changed the names to use ipf in some way to prevent name + * conflicts (since we do use get_random_bytes, means we need to include + * random.h, so there *WILL* be conflicts, and I figured I might as well + * protect the innocent while I was at it. + * Anyhow, here is the relevant code needed for get_random_int nearly verbatim. +*/ +/* + * Looks like they wern't kind enough to give us the prototype... + */ +//extern void get_random_bytes(void *buf, int nbytes); + + +__u32 ipf_secure_ip_id(__u32 daddr); +unsigned int ipf_get_random_int(void); +int ipf_seqgen_init(void); +int ipf_seqgen_fini(void); + + + diff -ruN ip_fil4.1.33/Linux/Makefile ip_fil4.1.33_modified/Linux/Makefile --- ip_fil4.1.33/Linux/Makefile 2009-07-18 15:13:30.000000000 -0400 +++ ip_fil4.1.33_modified/Linux/Makefile 2010-03-16 18:08:16.000000000 -0400 @@ -63,7 +63,7 @@ $(OBJ)/ip_frag.o $(OBJ)/ip_scan.o $(OBJ)/ip_sync.o \ $(OBJ)/ip_state.o $(OBJ)/ip_proxy.o $(OBJ)/ip_auth.o \ $(OBJ)/ip_lookup.o $(OBJ)/ip_pool.o $(OBJ)/ip_htable.o \ - $(OBJ)/ip_log.o $(OBJ)/radix.o + $(OBJ)/ip_log.o $(OBJ)/radix.o $(OBJ)/ip_gri.o KCCARGS=$(KCFLAGS) -D_BSD_SOURCE=1 $(IPFLKM) $(DEF) $(DLKM) -march=$(ARCH) \ $(INC) -iwithprefix include -I. $(LOOKUP) $(IPFLOG) IPF=$(OBJ)/ipf.o $(OBJ)/ipfcomp.o $(OBJ)/ipf_y.o $(OBJ)/ipf_l.o @@ -402,6 +402,15 @@ echo '#include "ipf-linux.h"' >> $@ sed -ne '/END OF INCLUDES/,$$p' $< >> $@ + +$(OBJ)/ip_gri.o: ip_gri.c $(TOP)/ip_gri.h $(TOP)/ip_compat.h \ + $(TOP)/ip_fil.h ipf-linux.h + $(CC) $(KCCARGS) -c ip_gri.c -o $@ + +ip_gri.c: $(TOP)/ip_gri.c Makefile + sed -e '/^#/,$$d' $< > $@ + sed -ne '/END OF INCLUDES/,$$p' $< >> $@ + ip_rules.c: $(TOP)/rules/ip_rules $(TOP)/tools/ipfcomp.o $(OBJ)/ipf $(OBJ)/ipf -cc -nf $(TOP)/rules/ip_rules @@ -446,6 +455,7 @@ $(OBJ)/ipmon_l.h: $(TOOL)/lexer.h (cd $(TOOL); make "DEST=../$(HERE)/$(OBJ)" ../$(HERE)/$@) + clean: ${RM} -f $(TOP)/ipf $(TOP)/ipnat $(TOP)/ipmon $(TOP)/ippool ${RM} -f $(TOP)/ipftest $(TOP)/ipscan $(TOP)/ipsyncm $(TOP)/ipsyncs @@ -453,7 +463,7 @@ ipfilter.o ${RM} -f fil.c ip_auth.c ip_frag.c ip_htable.c ip_lookup.c ip_log.c ${RM} -f ip_lookup.c ip_nat.c ip_pool.c ip_proxy.c ip_scan.c - ${RM} -f ip_state.c ip_sync.c radix.c ip_rules.c ip_rules.h + ${RM} -f ip_state.c ip_sync.c radix.c ip_rules.c ip_rules.h ip_gri.c ${MAKE} -f Makefile.ipsend ${MFLAGS} clean -(for i in Linux*; do \ if [ -d $${i} ] ; then \ diff -ruN ip_fil4.1.33/Linux/Makefile.kbuild ip_fil4.1.33_modified/Linux/Makefile.kbuild --- ip_fil4.1.33/Linux/Makefile.kbuild 2009-07-18 15:07:39.000000000 -0400 +++ ip_fil4.1.33_modified/Linux/Makefile.kbuild 2010-03-16 18:08:38.000000000 -0400 @@ -25,7 +25,7 @@ $(OBJ)/ip_frag.o $(OBJ)/ip_scan.o $(OBJ)/ip_sync.o \ $(OBJ)/ip_state.o $(OBJ)/ip_proxy.o $(OBJ)/ip_auth.o \ $(OBJ)/ip_lookup.o $(OBJ)/ip_pool.o $(OBJ)/ip_htable.o \ - $(OBJ)/ip_log.o $(OBJ)/radix.o + $(OBJ)/ip_log.o $(OBJ)/radix.o $(OBJ)/ip_gri.o obj-$(CONFIG_IPFILTER) += ipfilter.o ipfilter-objs =$(MODOBJS) @@ -111,6 +111,10 @@ echo '#include "ipf-linux.h"' >> $@ sed -ne '/END OF INCLUDES/,$$p' $< >> $@ +ip_gri.c $(obj)//ip_gri.c: $(TOP)/ip_gri.c Makefile + sed -e '/^#/,$$d' $< > $@ + sed -ne '/END OF INCLUDES/,$$p' $< >> $@ + ip_rules.c: $(TOP)/rules/ip_rules $(TOP)/tools/ipfcomp.o $(OBJ)/ipf $(OBJ)/ipf -cc -nf $(TOP)/rules/ip_rules @@ -146,6 +150,7 @@ $(obj)//ip_sync.o: $(obj)/ip_sync.c $(TOP)/ip_sync.h $(TOP)/ip_compat.h \ $(TOP)/ip_fil.h $(obj)/../ipf-linux.h $(obj)//radix.o: $(obj)/radix.c $(TOP)/radix_ipf.h $(obj)/../ipf-linux.h +$(obj)//ip_gri.o: $(obj)/ip_gri.c $(TOP)/ip_gri.h $(TOP)/ip_compat.h $(obj)/$(CPUDIR)/linux.o: $(obj)/$(CPUDIR)/linux.c $(obj)/$(CPUDIR)/fil.o: $(obj)/$(CPUDIR)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h \ $(TOP)/ip_compat.h $(obj)/../ipf-linux.h @@ -173,10 +178,13 @@ $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(obj)/../ipf-linux.h $(obj)/$(CPUDIR)/radix.o: $(obj)/$(CPUDIR)/radix.c $(TOP)/radix_ipf.h \ ipf-linux.h - +$(obj)/$(CPUDIR)/ip_gri.o: $(obj)/$(CPUDIR)/ip_gri.c $(TOP)/ip_gri.h \ + $(TOP)/ip_compat.h $(obj)/$(CPUDIR)/linuxm.c $(obj)//linuxm.c: $(TOP)/linux.c �...@if [ ! -h $@ ] ; then ln -s $< $@; fi $(obj)/$(CPUDIR)/ip_film.c $(obj)//ip_film.c: $(TOP)/ip_fil_linux.c �...@if [ ! -h $@ ] ; then ln -s $< $@; fi + + diff -ruN ip_fil4.1.33/linux.c ip_fil4.1.33_modified/linux.c --- ip_fil4.1.33/linux.c 2009-07-18 15:07:39.000000000 -0400 +++ ip_fil4.1.33_modified/linux.c 2010-03-16 19:06:50.000000000 -0400 @@ -264,6 +264,7 @@ static int ipfilter_init(void) { + ipf_seqgen_init(); #ifdef CONFIG_DEVFS_FS char *s; #endif @@ -346,6 +347,9 @@ static int ipfilter_fini(void) { + ipf_seqgen_fini(); + + int result; #ifdef CONFIG_DEVFS_FS char *s;
