pax_global_header00006660000000000000000000000064125060623110014506gustar00rootroot0000000000000052 comment=f7708f4c20fd489b33a480a4a1e5c391d131f9be iptables-optimizer-0.9.13/000077500000000000000000000000001250606231100154235ustar00rootroot00000000000000iptables-optimizer-0.9.13/.gitignore000066400000000000000000000000241250606231100174070ustar00rootroot00000000000000.tox/* docs/build/* iptables-optimizer-0.9.13/LICENSE.txt000066400000000000000000001043741250606231100172570ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . iptables-optimizer-0.9.13/MANIFEST000066400000000000000000000002051250606231100165510ustar00rootroot00000000000000# file GENERATED by distutils, do NOT edit README.txt iptables-optimizer iptables-optimizer-functions iptables_optimizer.py setup.py iptables-optimizer-0.9.13/Makefile000066400000000000000000000011111250606231100170550ustar00rootroot00000000000000# Makefile for opti.py, now needed for senseful tests # so there is nothing real to do, but pleasure alltests: @make shelltests testing shelltests: bash iptables-optimizer-tests.sh bash ip6tables-optimizer-tests.sh testing: /usr/bin/tox rpm: python3 setup.py bdist_rpm deb: gbp buildpackage --git-pbuilder doc: make -C docs html clean: make -C docs clean @python setup.py clean --bdist-base build @rm -rf .coverage *.pyc reference-output rs ts build @rm -rf __pycache__ iptables_optimizer.egg-info/ dist @rm -rf *.py3 .tox .noseids .pybuild @dh_clean || /bin/true iptables-optimizer-0.9.13/README.txt000066400000000000000000000042461250606231100171270ustar00rootroot00000000000000================== iptables-optimizer ================== Optimize kernel's iptables ruleset by usage. Author: Johannes Hubertz Date: 2015-02-10 Version: 0.9.13 License: GNU General Public License version 3 or later Benefit: Less interrupt load in a statistical point of view by minimizing latencies for any IPv4 or IPv6 packets slowed down by very long ip(6)tables chains. Costs: Small amount of additional user space workload. ip6tables-optimizer behaves like iptables-optimizer, except it uses ip6tables commands instead of iptables commands. The ip(6)tables-optimizer is intended to sort the chains in the running Linux-kernel, goal is to reduce latency of traversing packets. It runs as a shell script, which calls a python script. This sorts the chains by decreasing values of packet counters, afterwards the result is restored into the kernel. Of course, the administrators artwork in designing the rules is untouched, especially the presence of user defined chains, reject- or drop-rules is never changed. The only target are sequences of accept-rules, which are called partitions inside the script. Within these, there the rules are sorted. So it should be a challenge for the administrator to create his rules using as few policy- changes as possible within his ruleset to have a maximum benefit of the optimizer-script. Using shunit2 tests insure the wrapper part is as reliable as the python part of the ip(6)tables-optimizer. ip(6)tables-optimizer evaluates some line arguments: -a do not look for /var/cache/iptables-optimizer/auto-apply -c do not reset packet/byte counters on restoring tables -h to give this list of valid options -v add logging, twice shows partition tables in logs -w shows partition tables for INPUT and OUTPUT only Starting up the existance of an executable file is checked. /var/cache/iptables-optimizer/{auto-apply,auto-apply6} It is fed into the kernel by running ip(6)tables-restore and afterwards renamed following a simple date-time strategy. Thats my way of firing new rules into the kernel. Ideas, suggestions, comments welcome. Thanks for reading. Have fun! Johannes iptables-optimizer-0.9.13/docs/000077500000000000000000000000001250606231100163535ustar00rootroot00000000000000iptables-optimizer-0.9.13/docs/Makefile000066400000000000000000000130161250606231100200140ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext h: make html help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR) .ropeproject html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/iptables-optimizer.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/iptables-optimizer.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/iptables-optimizer" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/iptables-optimizer" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." iptables-optimizer-0.9.13/docs/source/000077500000000000000000000000001250606231100176535ustar00rootroot00000000000000iptables-optimizer-0.9.13/docs/source/conf.py000066400000000000000000000175231250606231100211620ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # iptables-optimizer documentation build configuration file, created by # sphinx-quickstart on Fri Aug 30 20:47:16 2013. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../')) sys.path.insert(0, os.path.abspath('../..')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'iptables-optimizer' copyright = u'2014, 2015, Johannes Hubertz' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.9' # The full version, including alpha/beta/rc tags. release = '0.9.13' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. #html_theme = 'default' html_theme = 'greencloud' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True html_use_index = False # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True html_show_sourcelink = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'iptables-optimizerdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'iptables-optimizer.tex', u'iptables-optimizer Documentation', u'Johannes Hubertz', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'iptables-optimizer', u'iptables-optimizer Documentation', [u'Johannes Hubertz'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'iptables-optimizer', u'iptables-optimizer Documentation', u'Johannes Hubertz', 'iptables-optimizer', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' iptables-optimizer-0.9.13/docs/source/cwfs.png000066400000000000000000000700351250606231100213300ustar00rootroot00000000000000PNG  IHDROWgAMA asRGB cHRMz&u0`:pQ<bKGD X pHYsHHFk>nIDATxg|E{ D4HG@HQ RAP)EzC ( *ws.WwOr^.$qovfvno4M40 ʕ+WW^j ZJRBPEY3<_U(l׮]#G)-Ww-$IrÇ/+;yIgO7nܸ!wܹRTI5jd0X-0pݻe#F(?6KJJJϜ9s铓}"߿Hٳg*:3iҤI۰aOh8RQqҥKyOrɓ\npppp^^tttZ}ڵkl]u@@lllV9tС4_u0yy-]tHԾ}MҺw]_ekXw3g߶m6p8'sΝ[Ru֭^ ãib6Ƭ̑#G,CmҤIٳŅ 466667wӭ+w޽ݻw)٫R3~gϞmMӴxzzzjժVÇΝ?r#޽{W hѢE h4ɓ'O.+;zQ~BBd^{58R\yͅ+VX#|~DDD)uرXܵk׮AӦM:J!hVV޺uV~|Zo?O>?6=ܻw^i۷+{[%bA _ED ͛7onɓ'z>~ƍ7v @ix{x{%'K/۲e˖#GYxzݓ'OlSQ^z饗ï_~quuu Ş={L:ur? BDңG\Qqax&5k֌൪ӥEEEEΝ%`[ [\8BQjZާO>7o޼ޛ}W_Ѵ`0XoʲtP/|ɓJUV^rJ**.\p!#cРA;O ,۸qF0+kĈ#> ATTTTݻG<=eʔ) %l36~nnSLRb .( t s8*իW+bk֬Yc-[4i vP? \|>_(lժU+Gb!I\.7=gddd}矧tر# KE1gϞ%@ `()))?t 9999D>I&M|}׮]V(lݺukq9>>>>!017z-իWvRHEO?SzzϞ={uڵmO߼yfs4iD*8p@gVދ/^ [ gYguK$)šqqqq RV\iӦM ,k׮u <®]v{ҥKA7z )rAPcfA11x<TV޹szV*,O?MN7n8^oiP'%FFFFΞ={vjjΝ;p)hѢSil^=zK.j HX,vs:uGIq$AD D".:N;J"\.p…IIK,YȮ xhŋ/vAPTiii)4u|AhhhDҿݾ}ϧ~)ABiK+CBpK}z{/_|9hvu]V_~:wQhK.׼y9]\\\hѢEz}^^^Xrqa+$ | ž}i4g \.>,,<>>>$~; !///϶sT-?s-f*SXf͚5z}fffNocoҦM6DQ;Q06 99oۖ/$!JkV lСC]]'L0A"ݻwE-]~` %>};u7xjQF钒=zM$%Nə8qDÇ=-[/Idd 2dHA(hѢꜶ4IٳgkbbbbjժU`A딢( w9 pg8f$^zZ4MI-Zh=x9mڴiץRvر t =yत&M4qIIII!&)qƍijgbbX+W]t´ ,M|p `AI6p8t˰Pضm۶_3zP}13R7%]vPtEEE)4k֬L6|՞|E ed߿RRhhhhi۷#uСsӿŋ 7L8Xpe2xÆ ꎈiC1s8nnnnRAAFV(hժU+.###I V AQURm۶m./?}i] >~q&"&@$ ^͛gnjΤ֦H%!х?T@JO.5j(&"fU4 )ݻw+b`x6l0W0Sl̘1c -s߫MI7| EL.[$ԩS' \VѣGۦ^b *ŋ/RTEEERqC010u֭Bw޽" Rqqqq{m0ڮ/ VRE?8Vg7qٝ BQVZ;{ Әטb67+*.^xsy m!"4ٳg@Є֯_]G>p۷on0ԞMk֬YQVi[&lxevpի*tsss߸qFd2WB@7ST_~i^y޽{+VX:T-t֭ZKHPU{%ȷ hѢ W7|M./0hϞ={U;3@t lڭs9$G&tT8[wR( ڥ\,=+\]_ojj4?`gxNNѴJRz[riXwwHe" ˪קߐjŰilرcŒ]v1/(((`0 < XWV_տ/rȑ#GA%%IWWWW0`*2 9f͚ޙ$bmcǎg`0 q 4Mee'N8QbŊ$!d#ܹsS֯_>=_~RS;t!))***c???Ǐ|}}}XH'BgX˗/Chķ6n X`0 AG8|UmK@^K/TS AuAbXN.7 $ԩS ͐`0  xfe3f z9S p?&䂇D5 ~hO4 Ri _~c0 `2P1-{! \7,,,,ǏC`e\./;q gWy{*BehإK.a`0 EA1^W7+:Ttǎ;\!}~ƀ;v`Z}`0 S'N.JI-[MSE=~PɆ 2$$̙3g `0G;k֬Y̒GF&%%%Znݺuξp `0cO?g?*յk׮&ӧOZ`0 8(VUIH̎~ۄ &81 `0ĉ'T߾}6iZtРA} `0p9>>>>(!i4s~~~~ξX `0LmB!m۶-Zs(ҠG4qL `0 ׸qI.+++Ci } `0Ẻ't `0 3itEPS`0 aaFRT+tIIIIΞX]5F:$)J$)d$)DΞ)`0L݂ h믿i4+G9R]|r?So61M$)4o޼Xꫯ>uԩ QTEEEEyٳg5"Itq(2 fḻ--/ߎ^a޽{**Ν;wxzΛ7oABi򸸸8]$СC6!!!6 nnSN--M^~Xܹsbqݻ>|!Tbpu9lذaf͚53=T}:eMeJ/bz~Aϟo蕕o߾ - \]'N8 \.eQFFxrs2e.׶q5wޭ駟~Bioh?~\^~ԩS(]v_}W-)-ݹsNxㅄo ;.SVZJ8*{݋~Fcaaa!Yֿx6/ޘWT\x"Yβ΂j'OΝ;W8pVjӦ2و#F111phkYJCegڨ}o$'5k֬VѣG(}3?,ʕ+W?ߝ -5뇲r\h(1///eDSx6sޘRRw};YMxaaaaρ-@2),\zjU@ رcnj3f8BM Caڵk&%5mڴBgϞ=ld'WRbTTTTQї_~%Mt:Jz}nnnu(^钓mNRZk׮]ii]t钚ڱcǎ:3(_dɒcǎeW =/$t**.]tz޲jկ+E;z xb `"'\dgO4iIH$ Z}ڵk+VXھ}3KJJJjuZVZBo=#֢v2iFj+S " `MaK]ĬPԳ*_0(ݻwAe˖ǥ?ò'N`ZfWP?LIn۶m[3& >|8srrrF5ʵ㩨8yvAZg1رcǬ,[Ʃ`1D>}4ET*Ue˖-KNn޼y󲲣GeyAcA^O&({F}czq]vgb h)c!????-W_}im Ҳx7s̙CG@,3 w-`5MtySA˟bآx͛M[\]'L0# 6C RX駟~jalyy .\[L5 |U:3Caaa!s4pI͛7>MBBBsܹs sU&^Μ9sf^ܹs:{ba4PbaL.]QQQ3mڴi&IR"H~Mcѫxxxx8Zq^`Vo?RYy͛-}NIiٲeKSڷo޶QE<*TGqƍ7[oY t."3!3336{E{έu֭.]tAx6Fp!S*>|tiiii[lk׮]) c 2#}[hѢtǎ;vbyy ,X1ΞH&Ful:tȐ!C#k1Z;&:Hh}GOC#=/*+++ll`0Wk}r>=g#"""P|L}?KÇm3kK7@i d7nܸHx/@gXHY.3f̘W^ꫯr [}~$t АvFTB-X,t\&JU*p\.#dL24y{}c_go̓u+ғ] T%"I=j_M$z E4a\Vvȑ#vm1E۷_tS\{s_}֬Y@yKg1p 0@OMMM5h?@^^}G[B5pm,ʨVL#=!!u<f}_-Z$ɧI9OOOO8O3r93f̘ٽ{;<{r,tA6Pg \$ϲyb磋CBBBlv~燆›a?'OD4Vfrz-ie@xޫVZ ٳgÿj7nߎR1x{/[lxF!(2DU,Sȓ'uԩ#֐- #,*7nܸa4* uQ@&{^m .\4h  .۸qFv?kLD֖Y;("WM | ƒHφI9 4 #YmLEUy`M왧m8p==df9r$zRzRhA ߶m۶l{N/'{IB1PEvLLLg}=Q~bq.]_~_5Jt!S**bVKbHo# X?h33G1@> S7Id2JK`0TK.]rUb }EW^yR6jtݻ^P 6ajmڴi .\<=]vnm <:vرL5٩8^W.\z> Nu1gΜ93,իW[ o"M0jIԊ8(J%sAӱޙ`J<,LmR^@ե__(D;vȴz ۵k׎Y`s ͭ[nJ{xM4i(U,NuB~駟l R*Uy 7n,t1E@_IF~4.A˖-[2X8h4.ssg͚5<><^ 裏>2uo8X oi=hFo߾}<=TVD]q)NKF q0D/Ba6mڠĿB: 7[€–-[d" hٳ ={۰z"hBn>F`xrsT 8jiJ#_~o:":8 OhjoŖ(&MӴr$IP]q{C1Q dn He؀qIϞ={6n?#ӧO=4ar7[/"LmTglҤI{-.ڼyfZFI5u0:QpDNLc%r\7wfR1&TgkpRJ*JQ2.SoNE- (u A~Pi85SbA"ݻwogݙh4wܹ۟[oFiYN_,DXꫯj@?rv6LgJfuodaÆ h Lrq}_8€dvvv6T=_3Fh"x^27#wfa5k:g=O iiGץ; AӀ,"dX>Ryȑ#gٓ5SZNԩSuͭi3v˙g ^ B@< g &2K.uq١iRR+JݻQ7oބB|JCUzH$AH'OLM| rs9EQsBjLHM2e [2=RO4Z-~;>pi(AYQqLozx̙3gg{q0SZV;{lG]U52"Q۶mۚ (TBʹ Qyx? Bo߾}'dj ^~-@R~Q[%Q"ͅO®\rñ9U4&9YǪ4FSaOM OS>I&M,VQU\tM #\^D\sPJ$ɩAU>))) ,HUwLc޽{ %$[n !A{TP${ T*Kt+Wd (&zp8^^^^ξ&PO^KP}%rѣG; {{/Yd D-\piG=-MWVVV EEEE*U|||<8 ]/Ғ;wts}z J4]Ru֭;Qo-Z`zZjC!Hm/fnwwwwB!5W׉'N8p@D!JPEXbEX˗/6(j$*;;;;'{ʔ)Se8`=xh}_3.l֚0+h½~7GnG8zQ_?;u7n8nPٳgӳju (y%si}sKzIO!###t4UHA!ٳ ԓ` cǎե$uܹ36mڔi?\o`ݻwk=z~.ThlVҗL+u Ro۵3*l2kzw!J(eeee[ Caaa!MJԩS [YgV0Ն ÀڞԠihn߾}[}&WǦgdddHzٓQ0ꉠ)DEEE1حiC!m۶+ʑX,3Mغu֮ &L`znqW_}mW'62|~dddFg m}bbbbxܚ m]i(kl8n-pD*0`w}]v{`4jLϕJU]ys6v!>ó6%`aye5O=4lȐ!CURy͐WP3"+$I :^LT>|0he׿ޙFy ww5IR*Jo(L9k֬Y5iv^Ӷts#b0G;'ckL |^ddd$Iڢ8 MӴ^bzV c;Jtu}7`z<3gnqʎ?~6Q&AŅϏm>RJ,Q*߿U{)] ٩׮]f)$bP!FCiii)h&u1l, (w޽mСCrr|7tw>}t󧥛۴iӦ9{TDI#ŴO&U( 5"AD ڣ^ `дM7P^~ٳqNϟ??+k̘1cl˟gIдSw3gdzB{lR]>>r΁AK& ۶mR}=<{{?ɓ'OΚ8qD tuf9e9;^-k@Dm<,#=IV3h,...FdM$);v,Njۿ~HQA[i}:.yxX2gA͛!Ւ9rD&:tPK-Aɇ:~3RTEEEE5o9,ΟߴiӦr1cƠ&sj߿_zՒo~KJʺJPE"uԩJuҥKp$i3C$)/#S!V煇RR~[Z}pazj mڴiY4DIz#S\]'M4xӦMfN8qBU? )\&N8.Y*u:D..%%%<...Lyɓ:}rrryϐK\h32<FJ8P&:tP{Ldsu۰a6QQ9999!D`vq\2gwiӦM رcǎO>]S ڷo>֒####CB?~\&1bK?/I޽{C2 xa/KTi 蚪fs.?w9_P-z{{{寿eJk1Ԑ <\c!!?EE1111p/yx̞={6ʹ:}JJJ ԣ7Y Φo߾=IewUssg͚5 o -Zh98@,SY[n ߯HܩSN۷o߶mSvI{l #2q/,\j*\6&$ߺuִ=z@b t֭[_xxxx0xZRm۶mI=z_~rw6m4K&?U; zjQiŊ+,A4 B%Vjy3$yh (V^nnn&M֚TW\9!ҝ;w4o_Q~.~uPhSt҅qN%=עEzMqƍc`{ 9+C?HةSNH++,\fXMh$I7)SLq(0tz$5OÀLK؏F`O WV޼y&s6mڴ ,\ M$~9Z׀jU?QNZhXD]0c{QP]vM$j׮];Tv \a%8Ç ps:uF/vr^^K,YÇ(fq0;{UjuܸqL#:!’$j>|ж5A4 h^_#4h4GZoMBBBB@ [R_ uGD۷tRLׯ_޺+[TYu15>k@Z'>+-:@̀G!>lGuw1c ֧:Dӏ}IH$!cFMA \.\Pӛ>dZQ(cz.h! a.\+Z{I@rrwڵkRpLCM Ol\d2wYfGHSN7i:/o 22 2D}[` Mt:$bjW?^*U|||믿:ӌ+h7"yXh,---M<,Xz`={<=Q^ .֯_:QE4ɼyAD:STyyy=Z?444Լn S(:5i4 mz/h]Y~G=*S8qūj|yG]`DGF&&&&} aXAf͚9Az~@PTTT֭[n'NL5KYٱcǎCUu`iJ/4ٳgï^zThu E4#~7r\~.X,*1///~o}h(}ɓ=O4$lip6͸ |c ~ cbpcǎy[S [ .,)ٲe㕕w޽ㅅiϯ)l 衦O bۣ#khZťiuhE,ٳgO#ސe,tʀ@ ^h(g9F_Hf }gT!3gO4MWV޹sNEŋ/VV޾}FsݻP 4ـ'#)-ݱctW ۺ&+ӡFsBNMzδB)9Gk%,T+kGQ~Ls:ϭ6:8H.l@S&&&&:w&\.;) aG χ8US]^-='XݤAbz0WjٮcahT( vCyd'--- =R3EJslHm1cJAUV^z5J{,hb0 ``*h6h9`0 q`A`0 `0 qX`0 8,hb0 `41 `0  `0M `0C&`0 !`A`0 `0 qX`0 8'`jP{c]vq!I$sqr\/(((oԨQ#/$$$ |>Wgfff¬2JRFg` D|ߟZE+1bPئM6*U|||^O "###5?@9qxxx8E)J%Zl3::::'{ʔ)S79prDtuuurE:t;vQ$zW^a뵪TKKo߾z?fR( -Q?t9s1RHk,***2?T߿?tСC=́G*J_L& 벼n[y.|>Z}ƍFgw.4]Zp…4oܾ}vPZ4i`铓 չs΁'8p`hϳu ee'N8dɒ%:}bbb?'(Z.J}Keeee*/ ||\ۡ(J}|`p|-Zh,...t:>iӦM](Kw)*յk׮14i+T.]2F}E-Gh޽{`Ei/o߾mkX^~̙3z}FFFsKKbccc~I=z*///o֭[LH$ox{^z5ΝiYex{ &z}NNNhO깰pʕ+a?]KCPEW_l߾}_KO BY/^xqnoV5jԨXܥK.Ν932 4(+kѣk1iL@ezVDvڵC >?222v׏pjsC.7 oܸqcVOǏ?.-￯+2L5h>,*BvW (4/9sq 'O|̘1c\___ڟ9xni4j(-~~)C >d E} <ޮsYbTA/0jkFI4~Db 49ǎ;ֶ~ʔ'N8QLܹs:{. z⣉hl9 {tiiiiBaIII <8OOOOw޽M[˳URJkyxݻ7| Cܮ!R~Hv5S"H؊c#BYɓ'O(7I&M*Ц7jt͛z}nnn.xk4---T]G9b,oUV˛?|^yy|Ν;xxxx8ݻW&1b-+;w:~Ξ#G:Kr"ĕÿ<ش ʎ;vL~mP23؉۷or(HD<GS]{tg}aÆ L)(?Foބ]@pIQ&sD@cSSB! ٝwK.]`tPݻw/59CWSX"۷o_Q MUuZW^ _)0Hu`c u>===6OJr\ShP W\L?ZÇ:1c0FB *ƅG@мygi4? h$I;ܖm۶Y4Bʔʽ{ek0(;T/Y@([9Do)ꫯ2])8@t:^ӦM9o޼ybq=z$bjзL6lذaLFgE!IC u>---`=d ;wܰK.]j3f̘A;}A4-+;u)ζŋC*uر=r8^~Lfa (C ZoS{Zp5߿E,ajo~A>٠0m;v3nB`f:i $QQQQmia =W=kҰft$Ce,///OMܹsgKFpvcC,(Xlٲ'sΝ4b-_ =WƏ?D`Kh]޽{,A9bAQe.M}!ȼ\>rȑG5 %LzD{g Y Ce2= P.a ӦB:k{]P7o޴\( тKq#> xsEHԮ]vr믿# %+9ݞ~VZ' `S]vzK0nݺu+ ~ibQݻٳgOe͛7o/&4Mj3IϞ={5f͚53-ij1G(l۶m[fֳmҤI#_S%šxWYyƍַ 0%#/2Y͡6j"qv1}>~/.;(YDܯ_~PX cIp\rG]D,իW/Gw 駟~& NЄ,EE_|;&< ÎP<|awynsYXJk?nnSL8AU,K̹ۄ &@}y)AӠ_~zVEϝ F^;}hi\>nܸq(VT?OQޜLaW>xRJ;wPZV#4iҤ?!IKU&w&ӂ4MӊR|Pzp0@獭J03XO)$5`k[筋Ҁ|4 Jɡ S7)B(-ݹsN׆AeڙիW]t~Pخ]vN<<իW٪k [p꺹rrrr@SQqٳ*յk׮U?AgE ]9(pt|~DDDDMkL4 s {UV؝[c////(rp(C9ǀCQbKmٳg?ߤ(۷oF"f&Ng3eZ%_&Ib1S=p"!;Ú ŋ/B;_u֭b1~C)W a-IWJ$h𒳾' T%ݻ7d5|/l޴߷>Xܹsh4M3(V4w&9vX@H59P=zs9܇ֳX4!<0 9w& J{pP*;v =(#'I -/?}ihL&#F@} xEx E6yCoMtnӧC6c$hRu'/A[O?sFb :zQ(qUzd:t*+;~qtM-Xы|'x x͚5k欙@HVẻ[jV→TW^j IHR)$|k48SNbbN~1.0(_U( 'w?ڜ-Ɣ$h]j?2> Waܨ@d>iӦMQڣ$vfpqqqQ*=zR=tYT^lOhh|||<Κ EllltEPx۶m,;u kSH^Yi-zch4WAxPs,R[p ܽ{nQXCSs4$Ao&/@tDc$7w֬Yjihx~wOˀ|yfjӧOnZڀ)K.]  P( 4N *** Y^~嗫zG{K{IݻwnSȷEJzCJSdz+VXӦ[m+:::(p͚5k5L4iM /3@Qڵk:N}\$Z&Kf@Wt73}3gu\> Nt.LLLL kŋ=nI$f~+ gweP%d-mn* @eZ믿U(vڵ H `=TR >v(JRѳi.)ongͣ:UMQ2oٲe ܇(s*@-(ѣfe2&iJ˜sѢEP]fhl/ vL4ky!{GxM2e Fi_Yy֭[rzq NL <~̖h!_^6iҤI_Ԁi?wڵk!!~ۇwu}7ްMAd~Am2153hQĠ/^4XpqV_u֭swG!Or5ZL>mڴi(ѫި[RO]vBy!Y??vGUG}Y^n^{ 淦O:5iN0aJ|( >|8Ru{-YdI,m۶mJ<nJKKKA?Jcm"x{ۓC([GoTU |刈{݋k +WWT37S 0g0;b&@esl߾}t4μ~Cd#FQh0 aܙ: ZF 10ʛ7o22225pog4 VZLyٳg:b1 `0GU( @K/D2T߿?Gv%c0 ` MtIw}9 aI^zA^TaÆ ξl `0cQ(ݻW믿B?K*ׯ_?i32}:iZ?~xh4g/`0 -hsrM6 ]ܦN: \.JДF1kҤI4ߜSNi`p`0 `쥠?ѣG"@ x߇#d|LT:tPV֘1cдV:{q0 `0L(*(Xjժµk׮ez;G|44Mu֭Z}L ۶m60pݻ–-[ta0 `ل|7+T/^ȴ32ѣG8////8NAD@w}AB!a ")5W^yFcqqq`0 ,.޸q͛7MnݺTh>466667Y9$!H$nӦM6qĉBaۣ'T`0 (_R_ӧ̙3g|ߛjQ򢣣ꫯغH룏>?zK.555Uw15#9r$5)/?suqs2eKRj׍(Arȑ#GWT\|2E)JykK.]HR&**lE1}ƌ3Z}ƍ#3f HU $r`W UVD;v4w8A;ZoVeMeBBBF{Ν;Zmbbb"ʹ(Ϛ5k-[0W낦ipBl-\>jԨQǏ?ӇkT. rzH`ܾ}\`=f̘1u2Ǎ7`s0 '#">|ϏԲtssg͚5ٳԌ\6f̘1!G=>zQzzϞ={ Ξ;}_{z>hZ32 4H|e{Fau:hYtI$#$&&&ٰڎ^[TTAAAAVرc2J6%$ӧeaÆ #ݻwTPz]^^^xܐO ,;w\Hc2#}Ȑ!C*TΝ;g7Ep%wލ^: yx̙3gNq͛7%8#ٳgHș3gΐD"XjI>+ ]vEgkQR4֯_~^`0 )))"""t:zVo63sѣƒgϫ6!r͛7w|:pOL귵~PV~رcJ#GM6moRXbŊósx/b`(bHe}7nܸ1<^xxx8$(?{Y{zh→:777`ի-Z6ELM0a(b,UI)ZC,ܹs瀀;w =q f *///۸qFKDG >֭[i\xz.X`A7o޼  M.d?Kr@a=}wk<=ϟ?*ӏ\>|RB-eC-+;rKkXܭ[n 4VT_|aA_3$64m4E1111ΞfЂ+Wԁ"Q:H+tGJ[Yɓ'OΘ1cF]1O9bĈryjj:ݿ#\pg l9n1𐐸8_ߘ܌5(tݻ ֬YFotĥbC]lJr6mhu ˗/_o9UT\t钥 %Kp8nnnnyOϟ?LH$I>+W\)2dHnԩSj4ݻg۵!{Ut' cʡ9]HR$"#aCeuIr… *?:]JJJ#:thyE\\\\OK}`rLLL l=vtJAM6m߷ǪY/MOڄ_~eg Wg>A)1UJJo*+?\ ͛7oxރt{tAvwPZZǎ;tiiiigx7|/@H**Ν;wŒ(}6bqݻWVe5jLP4>&eHB&ɘzY 9-[{,sΝoܸqrrf̘1úޚU\ pp||||[}tw}]pogMs Ryѣjk׮U?LVKx ̈́ZymڴiIOիW/_~k֬YtҥZYYYYyy͛+VXao x^G/ӧHԶm۶EE_~嗎XDž9U^E[\>>z>˖-[VX'|FnݺuÇ6mڴɺ 4g!?h!z-\.DFFFj>|h)Hj4wܹS>w]ܽ{V0D :xA'O ^`}!o5KKKKPNOݻwoʕ+W h6z]BQ֭[K${-0`Dҽ{..;`zgq%tEXtdate:create2014-09-01T13:07:18+02:000%tEXtdate:modify2014-09-01T13:07:18+02:00h?tEXtsvg:base-urifile:///home/hans/cwfs-1.0.0-original-0-degree.svg9աIENDB`iptables-optimizer-0.9.13/docs/source/index.rst000066400000000000000000000017611250606231100215210ustar00rootroot00000000000000.. iptables-optimizer documentation master file, created by sphinx-quickstart on Fri Aug 30 20:47:16 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. .. image:: cwfs.png :width: 220px :align: right :alt: latency **iptables-optimizer** is licensed under GNU GPLv3 or any later version Welcome to iptables-optimizer ============================= .. image:: latency.png :width: 550px :align: right :alt: latency **iptables-optimizer** is a shell script to be called by the root user. It calls some shell functions and a pyhton script to sort the current kernels iptables-chains in relation to the packet counters. Just run it by cron as often as you need it. Sounds crazy? Continue reading, please. Contents: .. toctree:: :maxdepth: 2 iptables-optimizer plausible shunit2 unittests sources Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` iptables-optimizer-0.9.13/docs/source/iptables-optimizer.rst000066400000000000000000000170671250606231100242430ustar00rootroot00000000000000========================== iptables-optimizer - intro ========================== In many SMB environments long term running packet filters are quite normal. Usually the administrators are often asked to add a rule for a special purpose, but only accidentally are kept informed about the end of life for the needs. So the set of rules grows over long time. Organizational rules may try to minimize this bad behavior, but nevertheless it is the normal way of doing. Assume you have a filtering Linux router with some thousands of iptables rules in its iptables chains. Unfortunately these this will produce latency for every traversing packet. And of course, this latency is unwanted behavior. The only useful way of improving is to reduce the length of the chains. Buts that is not easy if ever possible. Usually nobody is responsible enough to say, this special rule is no longer needed. You would like to know somebody for every rule. One of the first ideas for an optimization was to use the counters on each rule to see, if it is needed at all. The set of rules should run for a month and all those rules showing zero usage could be deleted. Sounds easy, but this is not as simple doing as said. Initial step to a solution was to add the beautiful comment module in every iptables-command and a number from the corresponding source of the rule. So it was easy to identify the iptables-command within the source. Nevertheless the finding of useless rules was not done because some lack of time. The latency grew. Another idea came up: partitioning of the long chains into parts of same targets. Within a partition the rules might be sorted on behalf of the packet counters so that the most often rules are searched first. And all the unused rules wouldn't be consulted so much often. Sounds crazy, but seemed to be `plausible `_. Tests were done, python was chosen for the programming part of the job. And a long and stony way started with the first step. shell wrapper ============= As IPv6 is coming soon, a simple modification in the wrappers source led to ip6tables-optimizer, which behaves exactly the same as iptables-optimizer... So the shell wrapper exists in two versions now, the second is symlinked to the first file. The shell wrapper simply acts in four steps after evaluating the options: 1. If an executable file ``/var/cache/iptables-optimizer/auto-apply`` exists, restore it into the kernel and rename it 2. Use ``iptables-save -t filter -c`` to store the kernels tables into a file 3. Run ``iptables_optimizer.py``, save stdout and stderr for errorchecking 4. Use ``iptables-restore`` to push back the rules into the kernel Some error-checking is done, so the code is a little bit more than four lines. In case of an error, the shell wrapper exits immediately due to runnig with ``bash -e``. The ``pipefail`` option ensures failures to be seen in piped commands as well. The real tricky things are done in the pythonic part. Some command line options are provided:: -a do not evaluate auto-apply (auto-apply6) -c keep the packet/byte counters on restoring -h help message about valid options and exit 1 -v verbose logging about the steps. If given twice, partitions and moves are logged -w logging partiontions and moves for INPUT and OUTPUT chains only, implies -vv, Usually the iptables-optimizer exits with a return value of zero indicating no error. The debian packaging produces two files for dpkg:: iptables-optimizer_x.y.z-v.deb iptables-optimizer-doc_x.y.z-v.deb For production environment the documents are not needed, for your understanding you do not need the binary package at all. All used functions within the shell wrapper are sourced from another file, ``iptables-optimizer-functions``. This seems to be useful for making them testable with Karen Wards shunit2, which is available as free software. python code =========== The only reason to have a shell wrapper for the python script was found in different python versions, which treated the subprocess module very different in different Debian stable versions from lenny to jessie. Python comes with batteries included, they say. The subprocess module can execute every shell command from within the python code. Sounds well, worked well until --- sometimes you have some different python versions running because of different operating systems, f.e. in Debian systems you may find python 2.5, 2.6, 2.7 and 3.2, 3.3 and 3.4, just like they are distributed as standard versions in etch, Lenny, squeeze and wheezy. Surprisingly the subprocess behavior changed a lot in these. I was very frustrated about that and therefore decided not to use it. Benefit was to have a single python script containing the necessary stuff without calling external commands, but running well in all different python versions. The external parts were migrated to an external shell script, which itself calls the python snippet for the complex actions now. So, what needs to be done? The filter tables are searched for every traversing packet, all the rules are checked for matching, and if one matches, its target is applied to the packet and usually the action for this packet is finished. The less rules must be searched the quicker the packet is forwarded or dropped. So the rules should be assorted in a way, more often used ones should be found quicker than those which are seldom used. But, there is a handicap: Perhaps the administrator wants some special packets to be dropped and some other to be forwarded. The old-fashioned handmade rule set respects this, and the administrators artwork shall never be destroyed by sorting. Let's think again, is it possible to sort the rules and to respect his artwork? Yes, it is possible, but few restrictions apply. In every chain we have some rules to accept, some to drop and some others, each intermixed with the others. From a mathematical point of view (set theory) partitions are the key to solve the puzzle. If we group consecutive rules having the same targets, inside these groups we can exchange the rule without changing the policy. Sure. So we have to find partition borders and then sort within each partition on behalf of the packet counters. Two python classes were build: Chain and Filter. An instance of the Filter class holds at least the predefined chains, perhaps some user defined chains. On creation of an instance it reads the given file. Fortunately the python code is completely independant of the rules content as it only evaluates the packet/byte counters. So it is used in the iptables-optimizer as well as in the ip6tables-optimizer. class Filter ------------ Instanciating the Filter class reads a file, which is an output of ``iptables-save -c``, so we get the chain names at first and then their content. For each chain an instance of the class Chain is set up. The packet counters are needed, this is done by the "-c" in the 2nd step of the wrapper. The init method ends up with a full representation of the kernels filter tables in memory. The opti method uses the opti method of all chain instances, the show method is just a wrapper around the many print statements for testing purposes and for better separating any additional information such as statistics, which then are printed out to stderr. This kind separation is fine, especially within the shell wrapper. class Chain ----------- On reading the file, an instance of the Chain class is build on the fly. The appends are done using the corresponding append method, and so at last a complete picture of the kernels view is in memory. The opti method on startup uses the make_partitions method prior to the sorting related to the packet counters. iptables-optimizer-0.9.13/docs/source/latency.png000066400000000000000000000551121250606231100220240ustar00rootroot00000000000000PNG  IHDRKbKGD IDATxy\Tʢ2(nWLfFf^PS)-+޸vJM R3E2Ar)5te!Ae;ΰ̰93y|:sΙy<0JV# ""F,DDD"`&"" 0XDLDD$`"""H,DDD"`&"" 0XDLDD$`"""H,DDD"`&"" 0XDld24ڊa2fs|ddd888L:6+gP,;SLqpp~i6GUT*1hdZrڬ\4[1,S\mI3|G:::]3Q7nTm֭[gQmHw$Xuyf*V Vٳ^tqq1I/jg_y֭[7m4$$̙3G7n͛7ԩ;s=$%%o߾_| KJJfϞ4]3kJaa;ӵkWGG-Z 2￯){Tmx״iӦMoݚm>}:$$iӦ[9sfqqМP(&Ongge;Cy)5/-Zigg׭[իWknژ~,N:վ}J7oܷo_7/ԩSCrꫯ$ȑ_5tM?5%4$$믿ֻd*bǏ_|yVVVVVܮ\Ri5Mr|Æ W^}饗͛WΟ?ߺu͛7߾}~ԩk rԩšU#iwn^3gεkW_9;;˗/\t_) {:thԨQH:X]:^t(99s|7ok{'|Rw/rMQUwT*ky{ڶm[U=>Ry}uĬROh"J}}ִ\.z G:b3f~uom>p޴ڟvE^͛+|ӦMn|Xö}铐TeƌwlGǮTWN8յqƏ?-[l=&tjufYRڵ j5iDsj8qb...ṹK:ޥ;5_Zc:~M?hggWIkԆ=~8VRRrvXmڴiPBb#~O-dpLDb믿>ð0@TTԕ+W^{50jԨ;w}wӦM3ga7!MZzzzTT؁X/iOtc<2L8{i&'' yپ}ҥK^z͞={ҤI oH/~DLDD$`"""H,DDD"`&"" 0XDLDD$`"""HR,]vd3J1cƌ!VxDDD 'R&O`͙EEEAAA~~~ BP$QIyK.=ydllӶ-[vxj&M۷o!RDDD "#'O[O>4?111,,LsNXXXBB C#""2$ 76o޼Ң3ghݻٳgM!I̙3=<<ϟ/<ݤIw6nXriiif߿/BDDD f+v%$$9sfՆmRWj""2ґT }T9??M=֭[...iYC|wS˷^MҚU;LC}2uŌ4j̈ۑ~FV?R|OOO ooSNiֳgOqb%""j0`U}XcccG)NDDD &ی3:x₂#GL>]츈< p͓=*rc״iS㪑.ԣZEj:ִcό)`F 0#u $t1՝jŒH 3"5̈p5ٗ_&O9 4v H5/^9RÌH 3">}zݺu?Ö-[:uSQFov^^޼yllll)0(Ilcx mHRvZG"]yɤ]/5XXDLDD$`2)H "IrC -XXɤ80#Dba&""6eXɤJ!fĬH5`2O&q1#Dba&;Œ7n͛7ԩ;s=W?SRRkoo_dEyzzum՚[Q('Ovwwٲe ~GV;uTʌ@*ȑ#ӧOԩS&M<<<}vdU* 0'ڿB ~ ^|9snݺ5&&&99YάYJJJ~u-[LJe:tΝ>oo._R}V^}ߺu맟~z{= U:;HDT'5}}wܹuBCC_ܹgQ<|͕wO SLywnڵ;}zN^^^˖-srrj\i)`]"#"#^}[._ܲeKK`˰h"C -̈dJJJw 8TZGŋڵS|͕󝝝iwww7j>}|+r `qzE&44TH 3"};t_}MJURRR^^^ݺuS_sqqR/\ٹ@yfm3<<P^^f͚_ER,o>pqfΜ9m۶7vww8q cǎb@Z۶m}}}6m ==]NNNYպQ[n}=?жm۾}A4MOZXe˖͛7xȑ#mVXXx>}}޽{!!!҈͛71S=iaF&&&F*STwĎŢX%R^&"35`Y`"""INjiaF,dRr\H 3"5̈`&;ŒH 3b=XDL&T*0#RÌX`28C -̈0#ǩ@DDT°ڵG 0r̈0#L#44TH 3"5̈|62eh(Yr2UPVnw_vlr 0ڈ"""Ɉ>YQ/`SdRb@ZaF$!0;}lHV_) C -̈0#]«DT [-)Q=\¥n2w7#`""ʾi 0Qe OOclL*<<\H 3"5̈­To+~׀P3:1B".t3VXy?Gaz 0T||!fDj%#n=ooC,dRr\H 3"5̈sF 0!fDjq|ȑӧwԩI&޾} Jr̘1NNNNNNcƌ+T""T'q2ZxڨےJ~7|}}ǢӧO;-) B\\\,nTJRH 3"5̈ԇ!Q%￿kݻwoҤСCە+W K׭[ׯ_ggggg爈}_^ܘ0#RÌK]Gb%\Uƍml4,,,!!AA"""0#RÌ('p=c7'|7n̙œ3ghӻwgϊYD$fhf{u"=usȐ!QEsVZ26""l2rgU*Jټy3gbbbަ#ǧ JRs111>ȳz 1f̘!z lAR slAB@ڿ&ThtUɓ' [ZZzivvoVVF0Q*;v; zfD,۰%~qܨ(Yt={nn0})ͥiii={#.j~H 3"5̈XMY |С=z>lllؑ#Me+Cn6,!!!77ƍ7n6m/,1cơC/^\PPPPP#%nT/$̈0#8 O_fR)͋ٳc>}v޽}ai͓=*rc״iSqczP(b@ZaFDcFlGH.rWaأ P}4L]`""j1 l,dRwē0#RÌRKLDD:d#U9qְǼLDDdӕ2Xj,dR#0#RÌR1b0<7Yɤr!fDjSڇ}%( l⭳IiaF1% H? `""NP`߀$`&R?1$fd~mēL*..NH 3"5̈ɨ??gQ Yɤ"""0#RÌL Q?%\:38CD^p%`2C -̈0#!Xj,dRb@ZaFLHĺ `2;iaF1C8C#ׯϘ1ćwڽ{w@@W_}1}ׯ2\2wb@ZaFi/CGڵwyٳgɩgϞoơCvqС]2\2w BH 3"5̈%#芮1 q;6|V 9vظqYI&iaF16čk6mfGGڬFDD$*}&&""kq'PhVɏ ?l0aZRM2Yf#F(,,4rld0#RÌ7!67xgwyYBc}F,ڵk0#RÌ7 d*J-Zzp)S 0cƌ/$ Y d!WAe<5CKNFrzZ @`9F@䓤o7oިQ4WdC[sϻ,$fxj{Y^/fi/FZbETTTTT$''4PA4hΝ;}}}Ϝ93cƌӧkÊkr!fDj#)D~ L HN2%síK'O{7t ,Xh?~>H}6z˗/? ^Wsy |ob,_?jF֧bggQ!,q"ڿxuDqٳW^fm۶q'N<(Q)JC -̈0#P-L>\VVb __-Zȴ)˗k9rm =ڧO'O)28C -̈0#p:WpGϬYz_zWn&%%^m͚5Æ ۚ1cz bѢEE-R(ԋ[` l-E R *@BC ej ?˫>彎nܸ1bĈ%K^3''˫HjLDD] ؃=QSe:6$[[[gggcl̐˗]ej շ9!om ׀ǎk.cǑ;|>6֭[ `bbb0#RÌ\af;qѤȺd̙~~~Gn׮^;?]#>;wn͚5=\~.^hRNjiaF10T_q(:lذ?ܼyO?ܼy@6mܹUV& ,\.;ŒH 3bRK4)@A)CY#4DҚ!CEV_b&R*b@ZaFN=?L,..NH 3"5H==#LK$_"5`""{a.r  >,7XBXj ?8/WPĈiaFiS83/v8z8ݻw?=++kΝ[bʼn'Mfkk;~xJ 44TH 3"5HC3(pmW^5kիW>}>>#G3c',""w8ߌ8i:VZ;wM63srrn޼٩S"cp,DDV:wDGTM&n: ͊  7o^VVfriaFD$CU__ }J38zQB#KP(0#RÌԛ?>y̙K/ lٲlٲ{<'O=zi­+&"(t}ܗAv :Z0/FGG۷///uݺu3F@LDd ŷc1xNeՑZ֭W_}e5z,s9 錄uqƹhѢ_~;wR3fӘ1c222D(<<\H 3"5H={|/L[Z޲eK~\\\* e8n޼sάUVEEE_^(((OP( ??b@vZC -̈0#p=OpjKUV\rʕsvv6RoG}.iiiG|rٲeǏW?iҤ}5`""%X`&f6.f']nذߤj;;;߿_x4o޼CWػw~o>Y.rWBbCP<ض{ի3g|||4WݻٳgM5i fDj:sBmA;:_=<,&&FT өz ’Z!%30e <րPS?]^^>k,77)Sxzz6jd;nܸ1bĈ%KkwssKKKsssS{hkDD,ЮA \ļlkkvڅ zyy̐KVO:9'--gϞ L@fN~Q}JV̀q>> >9'66vHۚ0#RÌԉz𜸑ԃT;?]ZXX3}3gXfƍO:մiS4*F+\Q .uAclES5]6)'N?RyIIIGrرc[}Ȃ%!I=Hרj|RV<==waH,??ō~0I aFjlQ|尰0ƍ{xx;2Hb@ZaFj( ܞSbS Ow555Ν;]t߿3gLY;iaF%3xy߹k#F={+V{1fl^DD1{n GDD** . N*y8«]P<}o&LꫯΝ;~zGGLDd48kd2n;܍6#^IȱYh82QQ_I/ߌe1a x*Y6s0#RÌ~H#y)2_k׮;ŒH 3<؃wH RN;a&""L&/vfDTM,dRr\H 3"5̈( (v8 UcGDu!~fD]/!ipYH _&,3tv>|a)JC -̈0#534AXWX1qD[[[0Nqqqb@ZaFjT2-Bp VCQqYODDEE=dX1[ F(a""Z*{2Ȟbc no7zwDG1Z}ўcƌ9z###vfZ&,`,5x׮]!!!oNMM >|ݻMYPC -̈0#Un Ӗq@}[&LМy+W9rĘ;ad$''u<9@ۛ67D4R@ӄ`:bwӧO2!C̘1=\Qzngy_;aIiaFVxoC{DF"2/jS{?W??̚5e˖a@,B;ŒH 3iWO<<]&y!* QQQ޹s/hѢ{M6ߴisbرcǎ۫WQ,<ldF `\77d!5QFi?srrvݯ_?Ær6HDDfJTLotۧ)v\߿; ` ۀ - 9uj۶mƍ'Nxyá;ŒH 3.gc` 7#1'O;(k׊iaF)EDLc##2) ۷뭷͛W7,E?3]JPp111sǫ[0x (_9ɗrv/?xWk,''˫MD `.>\hDF"*!8²2clXV͔查$̈XsF Q8hѢ\DS{[n0`QPrC -̈XsF#3|.֏۽{k׺wᅴ ҫW.^x…(PCiaFj3 a0ۣ~˗/ #U=<0x(W+]ؼys^ϟ?믿<""2ldOtazƅ!LxLnזVZuܹW_}x5;aIRرQ#̈XaFTP=ga7:CZe啬&ѣGݻ_^p+rcDF)..NH 3"5VX |QMPu+yyy111:uݧLbEDDiaF2RiЫ!y V#ӧOX=z[o-/((h߾ݻwd4d)<% ;v{89ѳ" 4 |ݻ/_~3g^xUVKYhzU}$'#:ZkNJ RRN# cǎ~ebRX6cFz2rcp$hD·%5\OχD2 iEi@<-5VSq<. }'a77߼ f [n5F@d٬ż0#Rc%Qz(kT ޯ_?͙~cf<&"]<7adL7<>woS~~~gΜ1F@d#`F3Ri+W__]\\*lZ&R(b@Z쌨7q@t YuӜ`K.I&"x Y !} ,0`LҾ}ׯoڴiӦM4F@DDd4zE5Z=СC7n8p333>)܌EDDO)J'bb1<>GbG$Z6m*--ڸqt' ;ŒHfҠW;"Y%R^&"ae(Q8-[E%)D$Lo bIjժ?W\Qi3A|DDd8UM+WܰaCHH "/v .ZuJ􄧨HP(x B@.iaFƒ29Kxɚk˞2M@NXDDPAp aQ5mڴ 6cDDdbP}e}/̴{&,R;ŒHedDsЫlkkvڅ zyy6$jnmTc|,vDeHy " 4A#85/"ADDTqx1 Q2kT*III#Fh߾0gĈ7f`DDdf4 @M^nOu'9sF,PLL!fDj:#Nږ۶m۷/4Nݽ{16KR䣴$.z q y 8;;Gf޿ְfjٲeJ1cƌaحi7cFL3i&L,gϞJ3 Jhhh6m>>55UV*ĨFOMM|V6[` l-Xs ^כ WfE5 #jKKKOA[k׊=ŒHdqa؍$!Rݐ)$&&vԩSsziPŪ0#Rc.'AH`CJ^^^+V0b\ڞ}ءCƎ9dڷv= ˱:)hBӧϜ95k6nxԩMֵ)""jld?DŽa7^K[E숌KS&+`W+]n޼yRRѣGr\.?vؾ}V_ ͞$̈H<#ʀ\RR`[*rEͺ[ܱc7Gb@ZxF>?'2ȾėZ̘#~k֬qqq)))IOO/2226lЬY3DYo<MDd(p~(^[bGd ƫ#LIIA^?ذa1b2 `""A%5[nnDaaa;w4F@dwʓD0#R#ٌhz%kT pXX֭[ .3޽ۨ:;ŒH439{x~cY߸qc׮]>|gϞݸqXDYo<MD@3U<ݮ]k׮;wn=|nݺؘr "" 2 ?@0QC|ob0b񘞴Ƃ&7g0#R#pIDATd#{&f c1 QXk &\XjJeǎŎaFF:QAa w!:>`LDT?3Wُq(}E2^?%Yd$'kv \x_}%L,Fe<TG1iF]uvicHNFJ 9%H22 ?@0~¡pd$@ ,CEXoC"""+D$Lo%c&"8)% ;ŒH8v )^ :X DkDDf_Hy|bVl;&5`""2 S6Ap_5bGdxJNFr=۲O4O h;hxL&/vf$9/Ѿ/70cz^(GxD R8BdJsXYt;1  /eQ 70`Z)Jc!>{œnbࣕ_}ț׀ɤbbb0#Rc>hf.I 9шFJ <|ͱ8Ll.,<KRرQ#̈40#q?KDx/ox~W#kp<=M}dnnnnjݺuPP{Qw5P2g`e\^6AXO1Y@9rm =ڧO'O$ u틾q|.J{{ۿ[QQQͫe5|u|||jj0T*5ĨOMM'-ԣa%'[lAf[ύkVh9\xyy^&>>~ҤIbGA0#RS­ @0bmgt6Ntֈ׀+ҥ 0Ym6s#t2, E Fgkmx B Ajsn00 /x} HT#>&'#%6M>(wGuX$C3<-5Tji2_~ɓiQiHt1Z& !0#rWśkF@?}/bFf<&"sQʌx+% ;E#TGª'`"2'uaG E6gymhRL<MOfD\HEꖦooXnGcBc7|V_eqň;Œ eH CXkD}_}fmdc b$3<MDrGbVlUBYi^a3nYۀFIbDG)h""s nö~7*-mv0)Ɗ@f"@0XB]ww`G2*-uXѿj'RRCIL*&&&""B(f~ů۰- (*-r8ӪƂz8'0Pk, ,dRb@Z:s[eJ\:bSx6Z˪ Zs8h` L&;^i-b$F!lUjڧ!NMDFrWWmm0j,P;؉&JMM;ŒU&2?ć.ш֬,+}գ2#փLJ'ŌT/9QQF^O04#+]{{̈3<MDyN:܉C~iq嚫7A:c-ip ""#\?Ŗq~xTw qc0-ڊ'Y ?@0頂*#=-n](YY5ma;bx.DKXj׮]+vUeqY.]\~ߏa\C!7AV\O,Dn­Zj/Q[F $׀QrH?3gqV8|A-[p7;s_;s::ù@½p4 2 `"29qG9.C\PWY_2JQZ:sp~6='G1jLFL&?i$GɈq % km4  ǟL&% ՞I3vNōKϹpOvPZ%eZ2:SBh٠P{GQb',")(Ei.rs#gfK6@zg\θ_]]U nƌ{ACTΙ30dȐ˗wAX*?=Я9:+AI.ru7N ݏZEB]ڠM]!j k]TT4uXfMppɓ'FTwըWog ӣ1L(,@0 QC`}֏X&''%Dsv|xK bp(-B=+AI1~! P*GmֳBҿܳ-+s35 mЦ-ںpWOAaZ%d@&a$br< 3g|||4֤/{Ff۸] =+9xGp<[7(cq0\Q> wN쩇76pQ\8nFHO((&yreזڪ׵CMTYV*fAuMѴV &"0>JM4{nƍsJKK5kvʫ._M_M+d@>\mڪ܊:y*Nd I8P #CP]ˊѹ;w/-` ~/z¬q'͹>^(<<\=*LZ^j{a-j1#`7747GweggfeeU^GEMUf8x6qSml{mUm8+klb4LdX4`8.ty@AB%ƀd*!#ȿ1E@0$9k!}lcȿ= }ڳv~]-i>k=ڥE~,I鱾O_HڐQ^V& ‘!i)2E?'BQrss҇2KeW:#GLD]سDKo=#wAmf(m4VRyyyww/zjYYơo%YBmeY'0W܈ݦoZ[~Bf,b5aYow(<ᷫ^v0ZGj4իWp{{{]]Ē{|cܗDI]0hZEE{キn:!|}Ŗ/--k|2M /sI$xj)7 M$b,ٴi_|!brhO/FC"FC"FwA' >Ѐ ]?# !0)k` S  RC:DD ]) X( 0lThU?f HhH:hաCdHhH:LD0`믿/e" I A6)!"Ν;# wֱ(k7JF@@ 3dg-Ԁkjj#]]]+Vб(k7JF@@ 3dg-Ԁo߾uVAAEYKP%7J&D=k"Zzz{v{xYYY>Խ:K7JF@@ 3dgͶ `ߚ5k GEEűcSN̬:}Ў;ǂ >C1'F&G${ח,Y/ uW^ٴiS 8~xkkW_}ZfS7lkkӼ߿dɒo޽G M]|yڵ7nQ7hllrJ_^7 ߿׮]OuS bΝуGF8yK/9++/֮]uV)GG^~ܶmzӋ/㲀؆y cE)**~`?9s4t;w.\x !ŋ+**o>{ 5kֹsWSO]paΜ9Ro6ԝ;wh f{nx`iii pyannb)rhhhҤ\ѯ!+c , !z{{#D_0''͛wBW1o޼ޣG>쳭O>=tm̙@@= b,2#0 \tI='DVSS9v57559sFYmʕԜrݧNR|gn;"59Έswt[mM1xȑ޽{-[D& oª>t?~|֭[ZJ7k֬EQÇNU-//L7 immmv}Μ9---_jUvv媩z/~ڴiNdͽՠ(JCCÌ3vE;訬t\.3"lhXZZ2B kH@@0Ѐ 4`$-KIENDB`iptables-optimizer-0.9.13/docs/source/plausible.rst000066400000000000000000000127211250606231100223700ustar00rootroot00000000000000Plausibility ============ Initial Scenario ---------------- Assume the following single chain as part of a NetFilter table, the number and the partition number rows are meta information and not taken from or represented in the kernel. (only meaningful content is shown here): +-----+------+----------+------+ | No | pkts | target | part | +=====+======+==========+======+ | 1 | 15 | accept | 1 | +-----+------+----------+------+ | 2 | 18 | accept | 1 | +-----+------+----------+------+ | 3 | 119 | accept | 1 | +-----+------+----------+------+ | 4 | 21 | drop | 2 | +-----+------+----------+------+ | 5 | 30 | accept | 3 | +-----+------+----------+------+ | 6 | 36 | accept | 3 | +-----+------+----------+------+ | 7 | 1 | userdef1 | 4 | +-----+------+----------+------+ | 8 | 5 | userdef2 | 5 | +-----+------+----------+------+ | 9 | 6 | drop | 6 | +-----+------+----------+------+ | 10 | 6 | drop | 6 | +-----+------+----------+------+ Partitions ---------- Partitions are assigned to the rules regarding their targets, starting with the first rule and the target accept. Rule 4 has another target, so rule 1, 2 and 3 build the first partition, the second partition starts with rule 4 and ends with it, because rule 5 has another target, so we continue until the end of the chain. At last we have found the partition table as a list:: partition numbers 1 2 3 4 5 6 partition list = [[1, 3], [4, 4], [5, 6], [7, 7], [8, 8], [9, 10], ] The list is constructed from elements, a two element list each. Every single element is build from the starting and ending number of the rules having the same target and an implicit length, which is easily calculated as:: length = 1 + end - start Viewed as a table it looks like: +-------------+-----------+----------+-------------+ | ``Part.No`` | ``Start`` | ``End`` | ``Length`` | +=============+===========+==========+=============+ | ``1`` | ``1`` | ``3`` | ``3`` | +-------------+-----------+----------+-------------+ | ``2`` | ``4`` | ``4`` | ``1`` | +-------------+-----------+----------+-------------+ | ``3`` | ``5`` | ``6`` | ``2`` | +-------------+-----------+----------+-------------+ | ``4`` | ``7`` | ``7`` | ``1`` | +-------------+-----------+----------+-------------+ | ``5`` | ``8`` | ``8`` | ``1`` | +-------------+-----------+----------+-------------+ | ``6`` | ``9`` | ``10`` | ``2`` | +-------------+-----------+----------+-------------+ Now lets concentrate on the first partition and the rules in it: +-----+------+----------+------+ | 1 | 15 | accept | 1 | +-----+------+----------+------+ | 2 | 18 | accept | 1 | +-----+------+----------+------+ | 3 | 119 | accept | 1 | +-----+------+----------+------+ We see, some (perhaps) different things shall be accepted by these three filter rules. So if a packet matches one of them or more, it is accepted. If it matches the third rule, the two before are consulted for nothing. Is the overall policy affected, if we change the position of the third rule to the top position? The answer is no, because the accepted traffic in sum is exactly the same regarding this partition of the complete rule set. So we can rearrange it to: +-----+------+----------+------+ | 3 | 119 | accept | 1 | +-----+------+----------+------+ | 2 | 18 | accept | 1 | +-----+------+----------+------+ | 1 | 15 | accept | 1 | +-----+------+----------+------+ As a result, the packets allowed by the now first rule are passed quicker because the other to rules are not taken into account. *Latency is reduced.* Partitions with a length of one are of no interest, surprisingly. Their content and their position are static all over the time. Exchanged rules --------------- Working down the partitions list, we come to this final result for the chain, the rule numbers are kept from the example shown above: +-----+------+----------+------+ | No | pkts | target | part | +=====+======+==========+======+ | 3 | 119 | accept | 1 | +-----+------+----------+------+ | 2 | 18 | accept | 1 | +-----+------+----------+------+ | 1 | 15 | accept | 1 | +-----+------+----------+------+ | 4 | 21 | drop | 2 | +-----+------+----------+------+ | 6 | 36 | accept | 3 | +-----+------+----------+------+ | 5 | 30 | accept | 3 | +-----+------+----------+------+ | 7 | 1 | userdef1 | 4 | +-----+------+----------+------+ | 8 | 5 | userdef2 | 5 | +-----+------+----------+------+ | 9 | 6 | drop | 6 | +-----+------+----------+------+ | 10 | 6 | drop | 6 | +-----+------+----------+------+ From the policy view, nothing has changed. Packets may pass as before or are dropped as before. But the kernel now finds the more often used rules quicker than before. Conclusion ---------- That is exactly what was intended by the swapping. The length of the partitions is not changed, for less latency the administrator should try to build as less partitions as possible. Exactly that is his artwork and no optimizer nor any other automatism can help him to solve this puzzle. How often shall this calculation be done? You have to find out yourself on your behalf. When I wrote the python code, it was run by cron every second on a dual core system and reducing latency for every end users joy. iptables-optimizer-0.9.13/docs/source/shunit2.rst000066400000000000000000000042421250606231100220030ustar00rootroot00000000000000========================================= iptables-optimizer-tests.sh - shell tests ========================================= shunit2 ------- Thanks to Kate Ward, who has build the shunit2, which is available in the debian universe. A reference file for input into iptables-optimizer is present as it is needed to run the tests. All the functions of the shell wrapper are sourced from an external file, so they may be tested independantly from the wrapper itself. Unfortunateley only root is allowed to run the iptables-optimier as it modifies the rules within the kernel. So the effctive uid is checked in the first test and all others are skipped if it is not zero. Excuting the tests is done like this as root user (uid=0):: .../opti# bash iptables-optimizer-tests.sh test_Needs_to_run_as_root test_AutoApply_Not_Present test_AutoApply_Not_Ready test_AutoApply_Ready test_AutoApply_Execute test_Modprobe_NetFilter test_Good_iptables_save_without_log test_Good_iptables_save_simple_log test_Run_python_part_without_log test_Run_python_part_simple_log test_Run_python_part_verb_log_all_chains test_Run_python_part_verb_log_in_out_chains test_Bad_iptables_save test_Correct_iptables_restore test_Faulty_iptables_restore Ran 15 tests. OK .../opti# If the executing user is not uid=0, the tests fail like this:: .../devel/opti master $ bash iptables-optimizer-tests.sh test_Needs_to_run_as_root ASSERT:[38] expecting-to-run-as-root expected:<0> but was:<1000> test_AutoApply_Not_Present test_AutoApply_Not_Ready test_AutoApply_Ready test_AutoApply_Execute test_Modprobe_NetFilter test_Good_iptables_save_without_log test_Good_iptables_save_simple_log test_Run_python_part_without_log test_Run_python_part_simple_log test_Run_python_part_verb_log_all_chains test_Run_python_part_verb_log_in_out_chains test_Bad_iptables_save test_Correct_iptables_restore test_Faulty_iptables_restore Ran 15 tests. FAILED (failures=1,skipped=18) .../devel/opti master $ As a consequence, the makefile will stop and no packages are build. So be sure to be root. Testing is great fun. iptables-optimizer-0.9.13/docs/source/sources.rst000066400000000000000000000002631250606231100220710ustar00rootroot00000000000000iptables-optimizer - python classes =================================== .. automodule:: iptables_optimizer :members: .. automodule:: iptables_optimizer_tests :members: iptables-optimizer-0.9.13/docs/source/unittests.rst000066400000000000000000000050431250606231100224510ustar00rootroot00000000000000======================================= iptables_optimizer_tests.py - unittests ======================================= nosetests --------- The two python classes come along with some unittests. A reference-input file is present as it is needed to run the tests. The prepared nosetests show like this:: nostests -v --with-coverage Chain_Test: create a chainobject ... ok Chain_Test: make partitions from no rules ... ok Chain_Test: make partitions from one rule a ... ok Chain_Test: make partitions from one rule d ... ok Chain_Test: make partitions from one rule r ... ok Chain_Test: make partitions from one rule l ... ok Chain_Test: make partitions from two rules aa ... ok Chain_Test: make partitions from two rules ad ... ok Chain_Test: make partitions from five rules adaaa ... ok Chain_Test: optimize an empty chainobject ... ok Chain_Test: optimize three rules aaa ... ok Chain_Test: optimize three rules aar ... ok Chain_Test: optimize five rules aalaa ... ok Filter_Test: non existant input-file ... ok Filter_Test: read reference-input ... ok Filter_Test: optimize, check 30 moves and partitions ... ok Filter_Test: check output for reference-input ... ok Name Stmts Miss Cover Missing -------------------------------------------------- iptables_optimizer 167 15 91% 33-34, 162-163, 236-246 ---------------------------------------------------------------------- Ran 17 tests in 0.048s OK The missing statements are the following:: 33 except: 34 pass # python2.6 162 except: 163 self.chains = {} # python2.6 236 file_to_read = "reference-input" 237 if len(sys.argv) > 1: 238 file_to_read = sys.argv[1] 239 try: 240 f = Filter(filename=file_to_read) 241 result, msg = f.opti() 242 sys.stderr.write(msg) # print partition-table to stderr 243 outmsg = f.show() 244 print(outmsg), 245 except KeyboardInterrupt as err: 246 print("\rUser stopped, execution terminated") That's not perfect, but it seems to be sufficient. tox --- This is done with the operating systems standard python. For your convenience, a **tox.ini** is present as well for tests using different python versions, for now these are Python2.7 and Python3.4 which are used in debian jessie. pep 8 ----- tox runs a pep 8 test as well, there are no complains. Testing is great fun. iptables-optimizer-0.9.13/ip6tables-optimizer000077700000000000000000000000001250606231100250202iptables-optimizerustar00rootroot00000000000000iptables-optimizer-0.9.13/ip6tables-optimizer-tests.sh000077700000000000000000000000001250606231100303422iptables-optimizer-tests.shustar00rootroot00000000000000iptables-optimizer-0.9.13/iptables-optimizer000077500000000000000000000100101250606231100211640ustar00rootroot00000000000000#!/bin/bash # # License: GNU General Public License version 3 or newer # Author: Johannes Hubertz # Version: 0.9.13 # Date: 2015-02-10 # # Fullname: /usr/sbin/iptables-optimizer # /usr/sbin/ip6tables-optimizer (works a symlink) # # optional command line switches: # -a suppress checking and applying of new rulesets # think twice because of concurrent iptables-commands # usually are not a very good idea! # # -c if present, no resetting the packet/byte counters # for easier long term debugging # # -h hint for options # # -v turns on logging, twice is more verbose # # -w verbose logging reduced to INPUT and OUTPUT chains # ############################################################## # iptables-optimizer runs in discrete steps: # # 0: if auto-apply is present, do it # done with shell commands # # 1: get iptables out of the kernel into file # done with shell commands # # 2: sort this file due to the counters into another file # done with pythonic intelligence # # 3: feed the second files iptables into the kernel # done with shell commands # # Almost every function was moved into another file, which is # sourced here. Simple reason for that is to enable the fine # tests with shunit2. All the tests for the shell and the # python part are included in the debian source package. # # Have fun! ############################################################## # # functions, files and paths are defined here # # first, no surprises by any language wanted export LANG=C # TRUE=0 FALSE=1 # # # NAME is for logging, the shorter the better! NAME="opti4" # # check if iptables or ip6tables, magic for the executables IP6="" [ `basename $0` == "ip6tables-optimizer" ] && IP6="6" && NAME="opti6" # IP6 now used wherever possible to keep the two sourcecodes in sync # # $AUTO points to new file containing new ruleset, # which comes from outside the iptables-optimizer AUTO__DIR=/var/cache/iptables-optimizer AUTO_FILE=auto-apply${IP6} AUTO=${AUTO__DIR}/${AUTO_FILE} # # all iptables-optimizer internal files reside here WORKBENCH=/var/run # # and yes, we want logging, less or verbose LOG="/usr/bin/logger -t $NAME -p user.warn " # # command line argument -c manipulates the variable COUNTER=0 # 0 => do reset packet/byte counters on the restore, default # 1 => do not reset packet/byte counters on restore # # command line argument -v manipulates the variable, # may be used more than once VERBLOG=0 # if 0, smallest logging, this is default # if 1, steps are logged # if 2, partition details are logged as well # # logging only for INPUT/OUTPUT or take all chains as default INOUT=$FALSE # # for -e switch and possible erroneous exits, always have be prepared ERROR_TEXT="starting up" # # take all the neccessary functions from file source iptables-optimizer-functions # ############################################### # # stop on first error, respect errors in pipes set -e set -o pipefail set -o errtrace trap error_func ERR # # evaluate command line arguments # while getopts ":achvw" opt; do case $opt in a) AUTO=${AUTO__DIR}/unwanted ;; c) COUNTER=1;; h) usage; exit 1;; v) VERBLOG=$(( ${VERBLOG} + 1 ));; w) INOUT=$TRUE; VERBLOG=2;; \?) echo "invalid option -- $OPTARG" >&2 ; usage; exit 1;; esac done ############################################### # # start the job here ERROR_TEXT="started up" log_start # # look if new rules are present and do neccessary actions ERROR_TEXT="checking ${AUTO}" check_auto_apply_ready "${AUTO}" && auto_apply_execute "${AUTO}" # cd $WORKBENCH # ERROR_TEXT="storing tables" save_the_tables ip${IP6}tables-optimizer-save-output ip${IP6}tables-optimizer-save-errors # ERROR_TEXT="running pythonic part" run_python_part ip${IP6}tables-optimizer-save-output ip${IP6}tables-optimizer-output ip${IP6}tables-optimizer-partitions $INOUT # ERROR_TEXT="restoring tables" load_the_tables ip${IP6}tables-optimizer-output ip${IP6}tables-optimizer-restore-out ip${IP6}tables-optimizer-restore-err $COUNTER # exit 0 # EoF iptables-optimizer-0.9.13/iptables-optimizer-functions000066400000000000000000000077151250606231100232110ustar00rootroot00000000000000# for missing shebang see: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html # # License: GNU General Public License version 3 or newer # Author: Johannes Hubertz # Version: 0.9.13 # Date: 2015-02-10 # # these functions are sourced in iptables-optimizer and it's tests usage() { echo "run as root, the valid options are:" echo "-a do not evaluate auto-apply" echo "-c do not reset packet/byte counters" echo "-h these hints for a correct usage" echo "-v verbose log, even more if given twice" echo "-w log about INPUT/OUTPUT chains only, implies -vv" } error_func() { echo "${ERROR_TEXT} (${BASH_SOURCE} line ${BASH_LINENO})" echo "${ERROR_TEXT} (${BASH_SOURCE} line ${BASH_LINENO})" | ${LOG} } log_start() { # at least one line always to syslog [ ${VERBLOG} -eq 0 ] && echo "starts" | ${LOG} return 0 } log_partitions() { # python puts this to stderr, show if wanted local _file=$1 local _inou=$2 FILTER="/bin/cat " [ -z "${_inou}" ] && _inou=$FALSE [ "${_inou}" -eq $TRUE ] && FILTER="/bin/egrep (INPUT|OUTPUT) " ${FILTER} ${_file} | ${LOG} return 0 } count_tables() { # just count the number of lines to log with a # given comment plus mentioning about errors local _file=$1 local _errv=$2 local _cmts=$3 local _cnt=$( cat ${_file} | wc -l ) local _fff='no' [ ${_errv} -ne 0 ] && _fff='with' echo "${_cmts} ${_cnt} rules, ${_fff} errors" | ${LOG} } check_auto_apply_ready() { # if file is readable and executable, say: Yes, do it. local _pathname=$1 [ -r ${_pathname} -a -x ${_pathname} ] && return $TRUE return $FALSE } auto_apply_execute() { # do it, restore a new ruleset into the kernel local _pathname=$1 local _DIRN=$(dirname ${_pathname}) local _FILE=$(basename ${_pathname}) local _DATE=$(/bin/date "+%Y%m%d-%H%M%S") local _NAME=${_DIRN}/${_FILE}-${_DATE} local _STDO=${_DIRN}/${_FILE}-stdout local _STDE=${_DIRN}/${_FILE}-stderr ERROR_TEXT="/sbin/ip${IP6}tables-restore -c < ${_pathname} >${_STDO} 2>${_STDE}" /sbin/ip${IP6}tables-restore -c < ${_pathname} >${_STDO} 2>${_STDE} retval=$? count_tables ${_pathname} ${retval} 'auto-apply:' [ ${retval} -ne 0 ] && return $FALSE ERROR_TEXT="/bin/mv ${_pathname} ${_NAME}" /bin/mv ${_pathname} ${_NAME} 2>&1 | $LOG retval=$? [ ${retval} -ne 0 ] && return $FALSE return $TRUE } save_the_tables() { # copy the kernels iptables to a file local _tables=$1 local _errors=$2 ERROR_TEXT="/sbin/ip${IP6}tables-save -t filter -c >${_tables} 2>${_errors}" /sbin/ip${IP6}tables-save -t filter -c >${_tables} 2>${_errors} retval=$? [ ${VERBLOG} -gt 0 ] && count_tables ${_tables} ${retval} 'Step 1:' [ ${retval} -eq 0 ] && return $TRUE return $FALSE } load_the_tables() { # copy from a file into the kernels iptables local _tables=$1 local _stdout=$2 local _stderr=$3 local _resetv=$4 RESET_VAL='-c' [ ${_resetv} -eq 0 ] && RESET_VAL='' ERROR_TEXT="/sbin/ip${IP6}tables-restore $RESET_VAL < ${_tables} >${_stdout} 2>${_stderr}" /sbin/ip${IP6}tables-restore $RESET_VAL < ${_tables} >${_stdout} 2>${_stderr} retval=$? [ ${VERBLOG} -eq 0 ] && count_tables ${_tables} ${retval} 'ready' [ ${VERBLOG} -gt 0 ] && count_tables ${_tables} ${retval} 'Step 3:' [ ${retval} -eq 0 ] && return $TRUE return $FALSE } run_python_part() { # do the python part of the job local _infile=$1 local _outfile=$2 local _partitions=$3 local _inout=$4 ERROR_TEXT="python iptables_optimizer.py ${_infile} >${_outfile} 2>${_partitions}" python iptables_optimizer.py ${_infile} >${_outfile} 2>${_partitions} retval=$? [ ${VERBLOG} -gt 0 ] && count_tables ${_outfile} ${retval} 'Step 2:' [ ${VERBLOG} -gt 1 ] && log_partitions ${_partitions} ${_inout} [ ${retval} -eq 0 ] && return $TRUE return $FALSE } #EoF iptables-optimizer-0.9.13/iptables-optimizer-tests.sh000077500000000000000000000163251250606231100227540ustar00rootroot00000000000000#!/bin/bash # Tests for all the shell functions needed by iptables-optimizer # 2015-01-16 # Johannes Hubertz # export TRUE=0 export FALSE=1 # default value for logging VERBLOG=0 CASUAL=/tmp/opti-tests-iptables-optimizer-tests.tmp-log IP6="" [ `basename $0` == "ip6tables-optimizer-tests.sh" ] && IP6="6" # fake LOG for the tests, do nothing casual_logger() { cat $* >$CASUAL } casual_log_lines() { LINES=$( cat $CASUAL | wc -l ) echo $LINES } LOG=casual_logger # are we root? ID=$(id -u) FAKED=$( printenv | grep -c FAKE ) REAL_ID=$(( $ID | $FAKED )) # first load the optimizer-functions . ./iptables-optimizer-functions test_Needs_to_run_as_root() { ${_ASSERT_EQUALS_} 'expecting-real-root' 0 ${REAL_ID} } test_AutoApply_Not_Present() { [ $REAL_ID -ne 0 ] && startSkipping # first check a non existing file for returning FALSE FILE="/tmp/opti-tests-auto-apply-not-present" check_auto_apply_ready $FILE retval=$? ${_ASSERT_EQUALS_} 'auto-apply-found-but-was-not-expeced' ${retval} $FALSE } test_AutoApply_Not_Ready() { [ $REAL_ID -ne 0 ] && startSkipping # create an existing file (0600) for returning FALSE FILE="/tmp/opti-tests-auto-apply-not-executable" touch ${FILE} chmod 600 ${FILE} check_auto_apply_ready ${FILE} retval=$? ${_ASSERT_EQUALS_} 'auto-apply-found-but-not-executable' ${retval} $FALSE } test_AutoApply_Ready() { [ $REAL_ID -ne 0 ] && startSkipping # create an existing file (0700) for returning TRUE FILE="/tmp/opti-tests-auto-apply" touch ${FILE} chmod 700 ${FILE} check_auto_apply_ready ${FILE} retval=$? ${_ASSERT_EQUALS_} 'auto-apply-found-like-expeted' ${retval} $TRUE } test_AutoApply_Execute() { [ $REAL_ID -ne 0 ] && startSkipping FILE="/tmp/opti-tests-auto-apply" touch ${FILE} chmod 700 ${FILE} auto_apply_execute $FILE retval=$? ${_ASSERT_EQUALS_} 'auto-apply-execute' $TRUE ${retval} PRESENT=$FALSE [ -f $FILE ] && PRESENT=$TRUE ${_ASSERT_EQUALS_} 'auto-apply-removed' $PRESENT $FALSE } test_AutoApply_Execute_fails_due_to_immutable() { [ $REAL_ID -ne 0 ] && startSkipping FILE="/tmp/opti-tests-auto-apply" touch ${FILE} chmod 700 ${FILE} # prevent moving after restore by setting immutable-bit [ $REAL_ID -eq 0 ] && chattr +i $FILE auto_apply_execute $FILE retval=$? ${_ASSERT_EQUALS_} 'auto-apply-execute' $TRUE ${retval} PRESENT=$FALSE [ -f $FILE ] && PRESENT=$TRUE ${_ASSERT_EQUALS_} 'auto-apply-removed' $PRESENT $TRUE # file still present, so reset immutable after test [ $REAL_ID -eq 0 ] && chattr -i $FILE rm -f $FILE } test_Modprobe_NetFilter() { [ $REAL_ID -ne 0 ] && startSkipping # try to load iptable modules /sbin/modprobe iptable_filter retval=$? ${_ASSERT_EQUALS_} 'modprobe-iptable_filter' $TRUE ${retval} } test_Good_iptables_save_without_log() { [ $REAL_ID -ne 0 ] && startSkipping # try to save iptables from the kernel TABLES="/tmp/opti-tests-iptables-save-output" ERRORS="/tmp/opti-tests-iptables-save-errors" VERBLOG=0 save_the_tables $TABLES $ERRORS retval=$? ${_ASSERT_EQUALS_} 'iptables-save' $TRUE ${retval} } test_Good_iptables_save_simple_log() { [ $REAL_ID -ne 0 ] && startSkipping # try to save iptables from the kernel TABLES="/tmp/opti-tests-iptables-save-output" ERRORS="/tmp/opti-tests-iptables-save-errors" VERBLOG=1 save_the_tables $TABLES $ERRORS retval=$? ${_ASSERT_EQUALS_} 'iptables-save' $TRUE ${retval} } test_Run_python_part_without_log() { [ $REAL_ID -ne 0 ] && startSkipping TABLES="/tmp/opti-tests-iptables-save-output" OPTOUT="/tmp/opti-tests-iptables-optimizer-output" STATIS="/tmp/opti-tests-iptables-optimizer-partitions" VERBLOG=0 run_python_part $TABLES $OPTOUT $STATIS retval=$? ${_ASSERT_EQUALS_} 'run-python-part' $TRUE ${retval} } test_Run_python_part_simple_log() { [ $REAL_ID -ne 0 ] && startSkipping TABLES="/tmp/opti-tests-iptables-save-output" OPTOUT="/tmp/opti-tests-iptables-optimizer-output" STATIS="/tmp/opti-tests-iptables-optimizer-partitions" VERBLOG=1 run_python_part $TABLES $OPTOUT $STATIS retval=$? ${_ASSERT_EQUALS_} 'run-python-part' $TRUE ${retval} } test_Run_python_part_verb_log_all_chains() { [ $REAL_ID -ne 0 ] && startSkipping TABLES="/tmp/opti-tests-iptables-save-output" OPTOUT="/tmp/opti-tests-iptables-optimizer-output" STATIS="/tmp/opti-tests-iptables-optimizer-partitions" VERBLOG=2 run_python_part $TABLES $OPTOUT $STATIS $FALSE retval=$? ${_ASSERT_EQUALS_} 'run-python-part' $TRUE ${retval} COUNT=$( casual_log_lines ) ${_ASSERT_EQUALS_} 'verbose:5-lines-expected ' 5 $COUNT } test_Run_python_part_verb_log_in_out_chains() { [ $REAL_ID -ne 0 ] && startSkipping TABLES="/tmp/opti-tests-iptables-save-output" OPTOUT="/tmp/opti-tests-iptables-optimizer-output" STATIS="/tmp/opti-tests-iptables-optimizer-partitions" VERBLOG=2 run_python_part $TABLES $OPTOUT $STATIS $TRUE retval=$? ${_ASSERT_EQUALS_} 'run-python-part' $TRUE ${retval} COUNT=$( casual_log_lines ) ${_ASSERT_EQUALS_} 'verbose:5-lines-expected ' 2 $COUNT } test_Bad_iptables_save() { [ $REAL_ID -ne 0 ] && startSkipping # try to save iptables from the kernel TABLES="/tmp/opti-tests-iptables-save-output" touch $TABLES chattr +i $TABLES >/dev/null 2>/dev/null retval=$? ${_ASSERT_EQUALS_} 'chattr-returned' $TRUE ${retval} FAULTS="/tmp/opti-tests-iptables-save-faults" VERBLOG=2 save_the_tables $TABLES $FAULTS 2>/dev/null retval=$? chattr -i $TABLES ${_ASSERT_EQUALS_} 'iptables-save' $FALSE ${retval} } test_Correct_iptables_restore() { [ $REAL_ID -ne 0 ] && startSkipping # try to restore iptables file into the kernel TABLES="/tmp/opti-tests-iptables-save-output" NORMAL="/tmp/opti-tests-iptables-restore-output" FAULTS="/tmp/opti-tests-iptables-restore-faults" COUNTS=1 load_the_tables $TABLES $NORMAL $FAULTS $COUNTS retval=$? ${_ASSERT_EQUALS_} 'iptables-restore' $TRUE ${retval} } test_Faulty_iptables_restore() { [ $REAL_ID -ne 0 ] && startSkipping # try to restore faulty iptables file into the kernel # create a faulty iptables statement and append TABLES="/tmp/opti-tests-iptables-save-output" NORMAL="/tmp/opti-tests-iptables-restore-output" FAULTS="/tmp/opti-tests-iptables-restore-faults" COUNTS=1 echo "/sbin/iptables -A OUTPUT -p udp --port 53 -j ACCEPT" >> $TABLES load_the_tables $TABLES $NORMAL $FAULTS $COUNTS retval=$? ${_ASSERT_EQUALS_} 'iptables-restore' $FALSE ${retval} } # some things before starting all these tests oneTimeSetUp() { [ $REAL_ID -eq 0 ] && ip${IP6}tables-save -c > /tmp/opti-tests-tables-before-status [ $REAL_ID -eq 0 ] && ip${IP6}tables -F [ $REAL_ID -eq 0 ] && ip${IP6}tables-restore -c reference-input${IP6} } # finalize some things after running all these tests oneTimeTearDown() { [ $REAL_ID -eq 0 ] && ip${IP6}tables -F [ $REAL_ID -eq 0 ] && ip${IP6}tables -X IPSEC [ $REAL_ID -eq 0 ] && ip${IP6}tables-restore -c /tmp/opti-tests-tables-before-status rm -f /tmp/opti* } # load shunit2 and execute the tests . shunit2 exit 0 iptables-optimizer-0.9.13/iptables_optimizer.py000077500000000000000000000205671250606231100217170ustar00rootroot00000000000000#!/usr/bin/python # -*- mode: python -*- # -*- coding: utf-8 -*- # """ iptables_optimizer.py: optimize iptables ruleset in userland in relation to usage (packet counters) Author: Johannes Hubertz johannes@hubertz.de Date: 2015-02-10 Version: 0.9.13 License: GNU General Public License version 3 or later This little helper is intended to optimize a large ruleset in iptables packetfilter chains, optimization target is throughput. All chains are partitioned now, sorting is done inside the partitions. Sequence of partitions is never changed, these are kept untouched for not destroying admistrators artwork. You will need a wrapper script, f.e. iptables-optimizer Comments, suggestions, improvements welcome! Have Fun! """ import sys try: from collections import OrderedDict as OptimizerDict except: OptimizerDict = dict # python2.6 def extract_pkt_cntr(cntrs): """given is a string: '[pkt_cntr:byt_cntr]', we need pkt_cntr and byt_cntr as set of return value for comparison""" br1 = cntrs.replace("[", "") br2 = br1.replace("]", "").strip() pkts, byts = br2.split(':') return (pkts, byts) class Chain(): """this is representation of one chain""" def __init__(self, name, policy): """create a chain just from it's name""" self.name = name self.policy = policy self.liste = [] self.cntrs = [] self.bytes = [] self.partitions = [] def append(self, line_list): """first fill in some content, line by line""" self.liste.append(line_list) cntrs = line_list[0] (cnt, byt) = extract_pkt_cntr(cntrs) self.cntrs.append(cnt) self.bytes.append(byt) def make_partitions(self): """make_partitions creates a list of 2-Elements-lists, each representing a consecutive sequence with ACCEPT, DROP, or the like. One 2-Element-list is called a partition, it is [p_strt, p_ende], and taken form self.liste Numbers in partions are Element-Positions, not indices! It returns len(self.partitions), used for testing purpose. """ self.partitions = [] # start with empty list number = 0 p_policy = "DROP" p_po_old = None p_strt = 1 p_ende = 1 last = len(self.liste) for index in range(0, last): # iterate complete list rule_txt = "" for k in self.liste[index]: rule_txt = rule_txt + k + " " if "ACCEPT" in rule_txt: p_policy = "ACCEPT" elif "DROP" in rule_txt: p_policy = "DROP" elif "REJECT" in rule_txt: p_policy = "REJECT" # we have mercy with LOG or the like else: # tribute to other targets number += 1 p_policy = "undef%05d" % (number) if p_po_old is None: # initialize old value once p_po_old = p_policy if (p_policy == p_po_old): p_ende = index + 1 else: self.partitions.append([p_strt, p_ende]) p_strt = index + 1 p_ende = index + 1 p_po_old = p_policy # special case: no rules in chain if len(self.liste) == 0: self.partitions = [] elif len(self.liste) == 1: self.partitions = [[1, 1]] else: self.partitions.append([p_strt, p_ende]) retval = len(self.partitions) return retval def find_ins_point(self, act, part_start): """find out, where to insert rule due to pkt-cntrs""" val = int(self.cntrs[act]) for run in range(part_start, act): if int(self.cntrs[run]) < val: return run def mov_up(self, position, part_start): """move position upwards where it belongs to list_point is found in cntrs (value start with 0), insert_point in kernel(value starts with 1) """ list_point = int(self.find_ins_point(position, part_start)) tmp_rule = self.liste.pop(position) self.liste.insert(list_point, tmp_rule) packet_cnt = self.cntrs.pop(position) self.cntrs.insert(list_point, packet_cnt) bytes_cnt = self.bytes.pop(position) self.bytes.insert(list_point, bytes_cnt) def opti(self): """optimize this chain due to packet counters""" ret_val = 0 len_val = len(self.liste) if len_val < 1: return (len_val, ret_val) self.make_partitions() for part in self.partitions: start = part[0] - 1 last = part[1] par_val = 0 for act in range(start + 1, last): if int(self.cntrs[act]) > int(self.cntrs[act - 1]): self.mov_up(act, start) par_val += 1 ret_val += 1 ret_val += par_val return (len_val, ret_val) class Filter(): """this is a filter group, may be filter, mangle, nat, raw, optimizer looks on filter group only! """ def __init__(self, groupname="filter", filename="reference-input"): """create a Filter object representing a filtergroup of iptables""" self.chains = OptimizerDict() # keep track of my chains self.groupname = groupname self.filename = filename try: pfile = open(filename, 'r') for line in pfile: # .split("\n"): line.replace(r"\n", " ") if line.startswith(":"): # first they are defined (c_name, policy, rest) = line.replace(":", "").split(" ") self.chains[c_name] = Chain(c_name, policy) else: # find chain_name from line, don't rely on position in file items = line.split(" ") for act in range(0, len(items)): if items[act] == '-A': c_name = items[act + 1] self.chains[c_name].append(items) except IOError as err: print(filename + ": ", err.strerror) def opti(self): """optimize all chains, one pass, and ready return sum of moved counts and partitions list for debugging """ ret_val = 0 omsg = "#chainname : moves partitions\n" for name in self.chains.keys(): (length, moved) = self.chains[name].opti() ret_val += moved parts = "" for part in self.chains[name].partitions: parts += str(part) omsg += "#%-11s: %5d %s\n" % (name, moved, parts) return (ret_val, omsg) def sequence(self): """keep track of all chainnames, predefined first with policy""" predefs = ['INPUT', 'FORWARD', 'OUTPUT'] head_list = [] cont_list = [] for nam in predefs: cont_list.append(nam) line = ":%s %s [0:0]" % (nam, self.chains[nam].policy) head_list.append(line) for nam in self.chains: if self.chains[nam].name not in predefs: cont_list.append(nam) line = ":%s - [0:0]" % (nam) head_list.append(line) return (head_list, cont_list) def show(self): """after sorting rules, print them out""" out = "# Generated by iptables-optimpizer.py from: " out += self.filename + '\n' out += "*%s\n" % (self.groupname) head, cont = self.sequence() for name in head: out += "%s\n" % (name) for name in cont: for this in self.chains[name].liste: line = "" for items in this: line += "%s " % (str(items)) out += line.strip() out += "\n" out += "COMMIT\n" out += "# Completed by iptables-optimizer.py from: %s\n" % \ (self.filename) return out if __name__ == "__main__": file_to_read = "reference-input" if len(sys.argv) > 1: file_to_read = sys.argv[1] try: f = Filter(filename=file_to_read) result, msg = f.opti() sys.stderr.write(msg) # print partition-table to stderr outmsg = f.show() print(outmsg), except KeyboardInterrupt as err: print("\rUser stopped, execution terminated") sys.exit(0) iptables-optimizer-0.9.13/iptables_optimizer_tests.py000066400000000000000000000306231250606231100231300ustar00rootroot00000000000000#!/usr/bin/python #encoding:utf8 from iptables_optimizer import extract_pkt_cntr, Chain, Filter import unittest class Chain_Test(unittest.TestCase): '''some first tests for class Chain''' def test_01_create_a_chainobject(self): """Chain_Test: create a chainobject""" c = Chain("FIRST_CHAIN", "ACCEPT") self.assertEquals("FIRST_CHAIN", c.name) self.assertEquals("ACCEPT", c.policy) self.assertEquals([], c.liste) self.assertEquals([], c.cntrs) self.assertEquals([], c.bytes) self.assertEquals([], c.partitions) def test_02_make_partitions_0(self): """Chain_Test: make partitions from no rules""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) self.assertEquals(0, c.make_partitions()) self.assertEquals([], c.partitions) def test_03_make_partitions_1a(self): """Chain_Test: make partitions from one rule a""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 1]], c.partitions) def test_04_make_partitions_1d(self): """Chain_Test: make partitions from one rule d""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j DROP' c.append(line.split(" ")) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 1]], c.partitions) def test_05_make_partitions_1r(self): """Chain_Test: make partitions from one rule r""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j REJECT' c.append(line.split(" ")) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 1]], c.partitions) def test_06_make_partitions_1l(self): """Chain_Test: make partitions from one rule l""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j LOG' c.append(line.split(" ")) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 1]], c.partitions) def test_07_make_partitions_2a(self): """Chain_Test: make partitions from two rules aa""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 2 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) line = '[18:23] -A INPUT -i sl0 -j ACCEPT' c.append(line.split(" ")) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 2]], c.partitions) def test_08_make_partitions_2ad(self): """Chain_Test: make partitions from two rules ad""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) # part 2: 2 - 2 line = '[18:23] -A INPUT -i sl2 -j DROP' c.append(line.split(" ")) self.assertEquals(2, c.make_partitions()) self.assertEquals([[1, 1], [2, 2]], c.partitions) def test_09_make_partitions_5ada(self): """Chain_Test: make partitions from five rules adaaa""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) # part 1: 1 - 1 line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) # part 2: 2 - 2 line = '[18:20] -A INPUT -i sl0 -j DROP' self.assertEquals(None, c.append(line.split(" "))) # part 3: 3 - 5 line = '[18:20] -A INPUT -i sl1 -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) line = '[18:20] -A INPUT -i sl2 -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) line = '[28:220] -A INPUT -i lo -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) # print "L:", c.liste self.assertEquals(3, c.make_partitions()) self.assertEquals([[1, 1], [2, 2], [3, 5]], c.partitions) def test_10_empty_opti_0(self): """Chain_Test: optimize an empty chainobject""" c = Chain("SECOND_CHAIN", "ACCEPT") self.assertEquals("SECOND_CHAIN", c.name) self.assertEquals("ACCEPT", c.policy) self.assertEquals([], c.liste) self.assertEquals([], c.cntrs) self.assertEquals([], c.bytes) self.assertEquals([], c.partitions) self.assertEquals((0, 0), c.opti()) def test_11_insert_three_aaa(self): """Chain_Test: optimize three rules aaa""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) self.assertEquals([['[9:10]', '-A', 'INPUT', '-p', 'tcp', '-m', 'tcp', '--dport', '23', '-j', 'ACCEPT']], c.liste) counters = line.split(" ")[0] (cnt, byt) = extract_pkt_cntr(counters) self.assertEquals(['9'], c.cntrs) self.assertEquals(['10'], c.bytes) line = '[18:20] -A INPUT -i sl0 -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) line = '[28:220] -A INPUT -i lo -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) result = [['[9:10]', '-A', 'INPUT', '-p', 'tcp', '-m', 'tcp', '--dport', '23', '-j', 'ACCEPT'], ['[18:20]', '-A', 'INPUT', '-i', 'sl0', '-j', 'ACCEPT'], ['[28:220]', '-A', 'INPUT', '-i', 'lo', '-j', 'ACCEPT']] self.assertEquals(result, c.liste) self.assertEquals(1, c.make_partitions()) self.assertEquals([[1, 3]], c.partitions) self.assertEquals((3, 4), c.opti()) def test_12_insert_three_aar(self): """Chain_Test: optimize three rules aar""" c = Chain("INPUT", "ACCEPT") self.assertEquals("INPUT", c.name) self.assertEquals("ACCEPT", c.policy) line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) self.assertEquals([['[9:10]', '-A', 'INPUT', '-p', 'tcp', '-m', 'tcp', '--dport', '23', '-j', 'ACCEPT']], c.liste) counters = line.split(" ")[0] (cnt, byt) = extract_pkt_cntr(counters) self.assertEquals(['9'], c.cntrs) self.assertEquals(['10'], c.bytes) line = '[18:20] -A INPUT -i sl0 -j ACCEPT' self.assertEquals(None, c.append(line.split(" "))) line = '[28:220] -A INPUT -i lo -j REJECT' self.assertEquals(None, c.append(line.split(" "))) result = [['[9:10]', '-A', 'INPUT', '-p', 'tcp', '-m', 'tcp', '--dport', '23', '-j', 'ACCEPT'], ['[18:20]', '-A', 'INPUT', '-i', 'sl0', '-j', 'ACCEPT'], ['[28:220]', '-A', 'INPUT', '-i', 'lo', '-j', 'REJECT']] self.assertEquals(result, c.liste) self.assertEquals(2, c.make_partitions()) self.assertEquals([[1, 2], [3, 3]], c.partitions) self.assertEquals((3, 2), c.opti()) def test_14_insert_five_rules_with_logdrop(self): """Chain_Test: optimize five rules aalaa""" c = Chain("INPUT", "DROP") self.assertEquals("INPUT", c.name) self.assertEquals("DROP", c.policy) line = '[9:10] -A INPUT -p tcp -m tcp --dport 23 -j ACCEPT' c.append(line.split(" ")) line = '[18:20] -A INPUT -i sl0 -j ACCEPT' c.append(line.split(" ")) line = '[83:436] -A INPUT -j logdrop' c.append(line.split(" ")) line = '[28:220] -A INPUT -i lo -j ACCEPT' c.append(line.split(" ")) line = '[18:20] -A INPUT -i sl1 -j ACCEPT' c.append(line.split(" ")) result = [['[9:10]', '-A', 'INPUT', '-p', 'tcp', '-m', 'tcp', '--dport', '23', '-j', 'ACCEPT'], ['[18:20]', '-A', 'INPUT', '-i', 'sl0', '-j', 'ACCEPT'], ['[83:436]', '-A', 'INPUT', '-j', 'logdrop'], ['[28:220]', '-A', 'INPUT', '-i', 'lo', '-j', 'ACCEPT'], ['[18:20]', '-A', 'INPUT', '-i', 'sl1', '-j', 'ACCEPT']] self.assertEquals(result, c.liste) self.assertEquals(3, c.make_partitions()) expect = [[1, 2], [3, 3], [4, 5]] #print "P:", c.partitions #print "W:", expect, " ... or something like that" self.assertEquals(expect, c.partitions) #self.assertTrue(False) # force textual output class Filter_Test(unittest.TestCase): '''some first tests for class Filter''' def test_01_filter_file_NOread(self): """Filter_Test: non existant input-file""" self.assertRaises(Filter("filter", "not-exist-is-OK")) def test_02_filter_file_OKread(self): """Filter_Test: read reference-input""" self.assertIsInstance(Filter("filter", "reference-input"), Filter) def test_03_optimize_algorithm(self): """Filter_Test: optimize, check 30 moves and partitions""" f = Filter("filter", "reference-input") cnt, msg = f.opti() expect = """#chainname : moves partitions #INPUT : 18 [1, 2][3, 3][4, 11][12, 12][13, 16][17, 17][18, 19] #FORWARD : 6 [1, 4][5, 5] #OUTPUT : 6 [1, 4][5, 5][6, 6] #IPSEC : 0 [1, 1] """ self.assertEquals(30, cnt) print(msg) self.assertEquals(expect, msg) def test_04_filter_output(self): """Filter_Test: check output for reference-input""" expect ="""# Generated by iptables-optimpizer.py from: reference-input *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :IPSEC - [0:0] [110:1234] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 21 -j ACCEPT [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [1630:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [150:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 750 -j ACCEPT [43:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 43 -j ACCEPT [42:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 42 -j ACCEPT [41:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 41 -j ACCEPT [10:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 10 -j ACCEPT [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [1:230] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 20 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [280:2200] -A INPUT -i lo -j ACCEPT [70:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 70 -j ACCEPT [60:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 60 -j ACCEPT [1:2323] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 23 -j ACCEPT [3:30] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 24 -j DROP [32:1260] -A INPUT -i eth3 -j ACCEPT [3:260] -A INPUT -i eth2 -j ACCEPT [4:123] -A FORWARD -i eth3 -o eth3 -j ACCEPT [3:123] -A FORWARD -i eth2 -o eth2 -j ACCEPT [2:123] -A FORWARD -i eth1 -o eth1 -j ACCEPT [1:123] -A FORWARD -s 10.0.0.0/8 -d 192.168.216.0/24 -j ACCEPT [1:123] -A FORWARD -j IPSEC [200:0] -A OUTPUT -p tcp -m tcp --sport 20 --dport 1024:65535 -j ACCEPT [50:123] -A OUTPUT -p tcp -m tcp --sport 23 --dport 1024:65535 -j ACCEPT [20:20] -A OUTPUT -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT [10:10] -A OUTPUT -o lo -j ACCEPT [80:123] -A OUTPUT -p tcp -m tcp --dport 25 -j REJECT [50:123] -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT [11:1123] -A IPSEC -j ACCEPT COMMIT # Completed by iptables-optimizer.py from: reference-input """ f = Filter("filter", "reference-input") f.opti() result = f.show() self.assertEquals(expect, result) if __name__ == "__main__": unittest.main() iptables-optimizer-0.9.13/man/000077500000000000000000000000001250606231100161765ustar00rootroot00000000000000iptables-optimizer-0.9.13/man/ip6tables-optimizer.8000066400000000000000000000102311250606231100221750ustar00rootroot00000000000000 .TH ip6tables-optimizer 8 "February 2015" "Johannes Hubertz" " " .SH NAME ip6tables-optimizer \- optimize ip6tables filter-chains in kernel depending on their usage counters .SH SYNOPSIS .B ip6tables-optimizer [-a] [-c] [-h] [-v[v]] [-w] .br .SH DESCRIPTION .B ip6tables-optimizer is used to sort ip6tables-rules in relation to the values of their packet-counters. And of course, administrators artwork is untouched. Sorting only happens in consecutive blocks of accept or drop statements, never across their borders. Therefore these blocks are called partitions and so they behave. ip6tables-optimizer is shipped in three files, a shell wrapper, functions to be sourced from it and a python exec. The sourced functions were neccessary because of testing them with .B shunit2, thanks to Karen Ward for this wonderful tool. The wrapper is my tribute to the changing function of python subprocess in different default python versions over some Debian releases. It runs in four steps, working directory is /var/run, id=0 is neccessary: .B 1.) /var/cache/ip6tables-optimizer/auto-apply6 is checked for read and exec flags. If so, the file is used as input on running ip6tables-restore, afterwards it is renamed. The renaming follows up a simple datetime strategy, this action is logged as well. Thats my way of firing new rules into the machine. They are copied using scp and after that marked as executable with chmod through ssh. .B 2) ip6tables-save -t filter -c > ip6tables-optimizer-save-output 2>ip6tables-optimizer-save-errors .B 3) ip6tables_optimizer.py ip6tables-optimizer-save-output >ip6tables-optimizer-output 2>ip6tables-optimizer-partitions .B 4) ip6tables-restore [ -c ] ip6tables-optimizer-output >ip6tables-optimizer-restore-out 2>ip6tables-optimizer-restore-err Of course, you might want to run it by cron every now and then. .SH "OPTIONS" .IP -a If given, it prevents the ip6tables-optimizer from handling the file .B /var/cache/ip6tables-optimizer/auto-apply6 .IP -c This option will prevent ip6tables-optimizer to reset paket/byte counters on restoring the tables, i.e these counters will be reloaded with the sorted rules. Intention is to support long term debugging sessions, because the position of the rules to be obeyed will be more stable. .IP -h Shows a brief help message about valid optional arguments and exits 1 .IP -v Verbose logging, i.e. reporting the steps and the number of rules. If given twice, the number of moves and the partitions as well. .IP -w reports INPUT and OUTPUT chain only, useful on non forwarding machines. .SH "FILES" .B /var/cache/ip6tables-optimizer keeps all the new rulesets, incomig new .B auto-apply6 is renamed to f.e. .B auto-apply6-20140818-091958 and kept there. Feel free to clean up these files or keep them as you like it. .B /var/run keeps the temporary files, their names all are beginning with .B ip6tables-optimizer- .SH "LOG" The handling of an executable file .B auto-apply6 is reported always. At least start and end of every program run is reported via syslog. Single verbose flag shows the three steps and the corresponding number of ip6tables commands. Two verbose flags additionally will show up the count of moves and the partitions of the chains. .SH "EXIT STATUS" ip6tables-optimizer usually returns a value of 0. Accidentially in case of error, f.e. if the ip6tables-restore fails, it returns the triggering error. .SH "COMPATIBILITY" ip6tables-optimizer .B should be compatible to any ip6tables implementations out in the wild. If not, keep me informed, thanks. I'll do my very best. .SH "HISTORY" ip6tables-optimizer has grown from first ideas over some more than two years and many errors to a productive state. First tries to use subproces within the python soon led into problems using different python versions on different debian releases. So these tasks were done on shell level, python testing and shell testing improved the solution. .SH "SEE ALSO" .BR ip6tables (8) .BR ip6tables-save (8) .BR ip6tables-restore (8) .SH "LICENSE" GNU General Public License version 3 or any newer version applies to ip6tables-optimizer. .SH "AUTHOR" Johannes Hubertz wrote this in 2012 - 2015. Anytime comments are welcome. iptables-optimizer-0.9.13/man/iptables-optimizer.8000066400000000000000000000101611250606231100221110ustar00rootroot00000000000000 .TH iptables-optimizer 8 "February 2015" "Johannes Hubertz" " " .SH NAME iptables-optimizer \- optimize iptables filter-chains in kernel depending on their usage counters .SH SYNOPSIS .B iptables-optimizer [-a] [-c] [-h] [-v[v]] [-w] .br .SH DESCRIPTION .B iptables-optimizer is used to sort iptables-rules in relation to the values of their packet-counters. And of course, administrators artwork is untouched. Sorting only happens in consecutive blocks of accept or drop statements, never across their borders. Therefore these blocks are called partitions and so they behave. iptables-optimizer is shipped in three files, a shell wrapper, functions to be sourced from it and a python exec. The sourced functions were neccessary because of testing them with .B shunit2, thanks to Karen Ward for this wonderful tool. The wrapper is my tribute to the changing function of python subprocess in different default python versions over some Debian releases. It runs in four steps, working directory is /var/run, id=0 is neccessary: .B 1.) /var/cache/iptables-optimizer/auto-apply is checked for read and exec flags. If so, the file is used as input on running iptables-restore, afterwards it is renamed. The renaming follows up a simple datetime strategy, this action is logged as well. Thats my way of firing new rules into the machine. They are copied using scp and after that marked as executable with chmod through ssh. .B 2) iptables-save -t filter -c > iptables-optimizer-save-output 2>iptables-optimizer-save-errors .B 3) iptables_optimizer.py iptables-optimizer-save-output >iptables-optimizer-output 2>iptables-optimizer-partitions .B 4) iptables-restore [ -c ] iptables-optimizer-output >iptables-optimizer-restore-out 2>iptables-optimizer-restore-err Of course, you might want to run it by cron every now and then. .SH "OPTIONS" .IP -a If given, it prevents the iptables-optimizer from handling the file .B /var/cache/iptables-optimizer/auto-apply .IP -c This option will prevent iptables-optimizer to reset paket/byte counters on restoring the tables, i.e these counters will be reloaded with the sorted rules. Intention is to support long term debugging sessions, because the position of the rules to be obeyed will be more stable. .IP -h Shows a brief help message about valid optional arguments and exits 1 .IP -v Verbose logging, i.e. reporting the steps and the number of rules. If given twice, the number of moves and the partitions as well. .IP -w reports INPUT and OUTPUT chain only, useful on non forwarding machines. .SH "FILES" .B /var/cache/iptables-optimizer keeps all the new rulesets, incomig new .B auto-apply is renamed to f.e. .B auto-apply-20140818-091958 and kept there. Feel free to clean up these files or keep them as you like it. .B /var/run keeps the temporary files, their names all are beginning with .B iptables-optimizer- .SH "LOG" The handling of an executable file .B auto-apply is reported always. At least start and end of every program run is reported via syslog. Single verbose flag shows the three steps and the corresponding number of iptables commands. Two verbose flags additionally will show up the count of moves and the partitions of the chains. .SH "EXIT STATUS" iptables-optimizer usually returns a value of 0. Accidentially in case of error, f.e. if the iptables-restore fails, it returns the triggering error. .SH "COMPATIBILITY" iptables-optimizer .B should be compatible to any iptables implementations out in the wild. If not, keep me informed, thanks. I'll do my very best. .SH "HISTORY" iptables-optimizer has grown from first ideas over some more than two years and many errors to a productive state. First tries to use subproces within the python soon led into problems using different python versions on different debian releases. So these tasks were done on shell level, python testing and shell testing improved the solution. .SH "SEE ALSO" .BR iptables (8) .BR iptables-save (8) .BR iptables-restore (8) .SH "LICENSE" GNU General Public License version 3 or any newer version applies to iptables-optimizer. .SH "AUTHOR" Johannes Hubertz wrote this in 2012 - 2015. Anytime comments are welcome. iptables-optimizer-0.9.13/reference-input000066400000000000000000000040241250606231100204410ustar00rootroot00000000000000# Generated by iptables-save v1.4.14 on Thu Nov 1 00:17:11 2012 *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :IPSEC - [0:0] [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [110:1234] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 21 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [1:230] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 20 -j ACCEPT [1630:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [150:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 750 -j ACCEPT [10:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 10 -j ACCEPT [41:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 41 -j ACCEPT [42:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 42 -j ACCEPT [43:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 43 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [60:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 60 -j ACCEPT [70:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 70 -j ACCEPT [1:2323] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 23 -j ACCEPT [280:2200] -A INPUT -i lo -j ACCEPT [3:30] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 24 -j DROP [32:1260] -A INPUT -i eth3 -j ACCEPT [3:260] -A INPUT -i eth2 -j ACCEPT [1:123] -A FORWARD -s 10.0.0.0/8 -d 192.168.216.0/24 -j ACCEPT [2:123] -A FORWARD -i eth1 -o eth1 -j ACCEPT [3:123] -A FORWARD -i eth2 -o eth2 -j ACCEPT [4:123] -A FORWARD -i eth3 -o eth3 -j ACCEPT [1:123] -A FORWARD -j IPSEC [10:10] -A OUTPUT -o lo -j ACCEPT [20:20] -A OUTPUT -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT [200:0] -A OUTPUT -p tcp -m tcp --sport 20 --dport 1024:65535 -j ACCEPT [50:123] -A OUTPUT -p tcp -m tcp --sport 23 --dport 1024:65535 -j ACCEPT [80:123] -A OUTPUT -p tcp -m tcp --dport 25 -j REJECT [50:123] -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT [11:1123] -A IPSEC -j ACCEPT COMMIT # Completed on Thu Nov 1 00:17:13 2012 iptables-optimizer-0.9.13/reference-input6000066400000000000000000000040731250606231100205330ustar00rootroot00000000000000# Generated by iptables-save v1.4.14 on Thu Nov 1 00:17:11 2012 *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :IPSEC - [0:0] [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [110:1234] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 21 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [9:10] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [1:230] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 20 -j ACCEPT [1630:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 23 -j ACCEPT [150:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 750 -j ACCEPT [10:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 10 -j ACCEPT [41:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 41 -j ACCEPT [42:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 42 -j ACCEPT [43:90] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 43 -j ACCEPT [50:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 50 -j DROP [60:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 60 -j ACCEPT [70:2323] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 70 -j ACCEPT [1:2323] -A INPUT -p tcp -m tcp --sport 1024:65535 --dport 23 -j ACCEPT [280:2200] -A INPUT -i lo -j ACCEPT [3:30] -A INPUT -p tcp -m tcp --sport 0:65535 --dport 24 -j DROP [32:1260] -A INPUT -i eth3 -j ACCEPT [3:260] -A INPUT -i eth2 -j ACCEPT [1:123] -A INPUT -d fe80::/12 -s 2000::/3 -j ACCEPT [1:123] -A OUTPUT -s fe80::/12 -d 2000::/3 -j ACCEPT [1:123] -A FORWARD -s fe80::/12 -d 2000::/3 -j ACCEPT [2:123] -A FORWARD -i eth1 -o eth1 -j ACCEPT [3:123] -A FORWARD -i eth2 -o eth2 -j ACCEPT [4:123] -A FORWARD -i eth3 -o eth3 -j ACCEPT [10:10] -A OUTPUT -o lo -j ACCEPT [20:20] -A OUTPUT -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT [200:0] -A OUTPUT -p tcp -m tcp --sport 20 --dport 1024:65535 -j ACCEPT [50:123] -A OUTPUT -p tcp -m tcp --sport 23 --dport 1024:65535 -j ACCEPT [80:123] -A OUTPUT -p tcp -m tcp --dport 25 -j REJECT [50:123] -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT COMMIT # Completed on Thu Nov 1 00:17:13 2012 iptables-optimizer-0.9.13/setup.py000066400000000000000000000021541250606231100171370ustar00rootroot00000000000000#!/usr/bin/python import sys from setuptools import setup, find_packages kw = {} if sys.version_info >= (3,): kw['use_2to3'] = True setup(name='iptables-optimizer', description='runtime iptables sorting by packet counters', long_description=open('README.txt').read(), version='0.9.13', license='GNU General Public License version 3 (or later)', platforms=['Linux'], author='Johannes Hubertz', author_email='johannes@hubertz.de', url='https://github.com/sl0/opti.git', classifiers=[ 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 'Intended Audience :: System Administrators', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Topic :: Security', 'Topic :: System :: Networking :: Firewalls', 'Topic :: Utilities', ], py_modules=['iptables_optimizer'], scripts=['iptables-optimizer', 'ip6tables-optimizer', 'iptables-optimizer-functions'], **kw ) iptables-optimizer-0.9.13/tox.ini000066400000000000000000000021531250606231100167370ustar00rootroot00000000000000# Tox (http://tox.testrun.org/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] envlist = py27, py34, pep8, flak [testenv] #commands = /usr/bin/nosetests-2.7 /usr/bin/nosetests3 #[testenv:py26] #basepython = # python2.6 #commands = # python setup.py clean # python setup.py build # /usr/bin/nosetests -v iptables_optimizer_tests.py [testenv:py27] basepython = python2.7 commands = python2.7 setup.py clean python2.7 setup.py build /usr/bin/python2.7 -m pytest iptables_optimizer_tests.py [testenv:py34] basepython = python3.4 commands = /usr/bin/2to3 --add-suffix='3' -n -w ./iptables_optimizer.py /usr/bin/python3.4 setup.py clean /usr/bin/python3.4 setup.py build /usr/bin/python3.4 -m pytest iptables_optimizer_tests.py [testenv:pep8] commands = /usr/bin/pep8 --show-pep8 --show-source iptables_optimizer.py [testenv:flak] basepython = python2.7 commands = /usr/bin/pyflakes iptables_optimizer.py