├── .gitignore ├── LICENSE ├── README.md ├── examples ├── README.md └── accounting.nft ├── location.csv └── nft_geoip.py /.gitignore: -------------------------------------------------------------------------------- 1 | geoip-*.nft 2 | dbip.csv 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nftables geoip script 2 | 3 | Python script that generates .nft files with mappings between IP addresses 4 | and its geolocation, so you can include them inside your rules. 5 | 6 | 7 | # Requirements 8 | 9 | Minimum python version: **3.9** 10 | 11 | Package used that are not present in the Python Standard Library 12 | 13 | - `requests` 14 | 15 | 16 | # Usage example 17 | 18 | To generate ipv4 and ipv6 mappings, download geoip data from db-ip.com 19 | saving the output in the current folder 20 | 21 | ``` 22 | ./nft_geoip.py --file-location location.csv --download 23 | ``` 24 | 25 | Giving the following output 26 | 27 | ``` 28 | drwxr-xr-x 2 foobar foobar 4,0K ene 4 19:38 . 29 | drwxr-xr-x 5 foobar foobar 4,0K ene 4 19:38 .. 30 | -rw-r--r-- 1 foobar foobar 22M ene 4 19:38 dbip.csv 31 | -rw-r--r-- 1 foobar foobar 956 ene 4 19:38 geoip-def-africa.nft 32 | -rw-r--r-- 1 foobar foobar 8,3K ene 4 19:38 geoip-def-all.nft 33 | -rw-r--r-- 1 foobar foobar 902 ene 4 19:38 geoip-def-americas.nft 34 | -rw-r--r-- 1 foobar foobar 15 ene 4 19:38 geoip-def-antarctica.nft 35 | -rw-r--r-- 1 foobar foobar 808 ene 4 19:38 geoip-def-asia.nft 36 | -rw-r--r-- 1 foobar foobar 810 ene 4 19:38 geoip-def-europe.nft 37 | -rw-r--r-- 1 foobar foobar 461 ene 4 19:38 geoip-def-oceania.nft 38 | -rw-r--r-- 1 foobar foobar 8,8M ene 4 19:38 geoip-ipv4.nft 39 | -rw-r--r-- 1 foobar foobar 16M ene 4 19:38 geoip-ipv6.nft 40 | ``` 41 | 42 | * geoip-def-all defines variables for each country (2-char iso name) 43 | in location.csv assigning its iso numeric value (eg. Canada, `define $CA = 124`) 44 | * geoip-ipv4.nft defines geoip4 map (@geoip4) 45 | * geoip-ipv6.nft defines geoip6 map (@geoip6) 46 | 47 | ## Creating a country filtered subset for `geoip-*.nft` files 48 | 49 | If you don't want the whole geoip map (including all countries) you can filter 50 | by country using the `-c/--country-filter` parameter. This parameter enables 51 | the creation of the additional files: 52 | 53 | - geoip-ipv4-interesting.nft 54 | - geoip-ipv6-interesting.nft 55 | 56 | These files will contain nft maps with addresses related to the specified 57 | countries only. 58 | 59 | For example, to generate a Spanish, French and Portuguese only subset: 60 | 61 | ``` 62 | ./nft_geoip.py --download -c es,fr,pt 63 | ... 64 | Found countries: {'france': 'fr', 'spain': 'es'} 65 | Writing interesting countries file... 66 | Done! 67 | ``` 68 | 69 | ## Marking packets to its corresponding country 70 | 71 | Most importantly, using the maps you mark ipv4 and ipv6 packets with 72 | 73 | ``` 74 | meta mark set ip saddr map @geoip4 75 | meta mark set ip saddr map @geoip6 76 | ``` 77 | 78 | You can mark output and input packets adding a chain with the 79 | lowest priority among all of other chains in your table. 80 | 81 | ### Marking output packets by destination 82 | ``` 83 | chain geoip-mark-output { 84 | type filter hook output priority -1; policy accept; 85 | 86 | meta mark set ip daddr map @geoip4 87 | meta mark set ip6 daddr map @geoip6 88 | } 89 | ``` 90 | 91 | ### Marking input packet by origin 92 | ``` 93 | chain geoip-mark-input { 94 | type filter hook input priority -1; policy accept; 95 | 96 | meta mark set ip saddr map @geoip4 97 | meta mark set ip saddr map @geoip6 98 | } 99 | ``` 100 | 101 | ## Example: Counting incoming Spanish traffic 102 | 103 | Create a file, `geoip.nft` (it will be at `/etc/geoip.nft` for this example). 104 | ``` 105 | #!/usr/sbin/nft -f 106 | 107 | table inet geoip { 108 | include "geoip-def-all.nft" 109 | include "geoip-ipv4.nft" 110 | include "geoip-ipv6.nft" 111 | 112 | chain geoip-mark-input { 113 | type filter hook input priority -1; policy accept; 114 | 115 | meta mark set ip saddr map @geoip4 116 | meta mark set ip6 saddr map @geoip6 117 | } 118 | 119 | chain input { 120 | type filter hook input priority 0; policy accept; 121 | 122 | meta mark $ES counter 123 | } 124 | } 125 | ``` 126 | __NOTE:__ If you plan on using both ipv4 and ipv6 sets you need to use the `inet` prefix for the table type. 127 | 128 | Then run ```nft -f /etc/geoip.nft``` to add it to your firewall. 129 | 130 | You can also make the new table, chain and rules permanent by editing your distro specific file 131 | (/etc/nftables.conf for Arch Linux or Debian) by including `geoip.nft`. This file is usually run at boot. 132 | ``` 133 | #!/usr/sbin/nft -f 134 | 135 | flush ruleset 136 | include "/etc/geoip.nft" 137 | 138 | # your ruleset... 139 | 140 | ... 141 | ``` 142 | 143 | When updating the geoip maps (`geoip-ipv4` and/or `geoip-ipv6`), you will need to 144 | reload `/etc/geoip.nft` so new geoip maps are included again and old ones dropped: 145 | ``` 146 | nft delete table geoip 147 | nft -f /etc/geoip.nft 148 | ``` 149 | 150 | ## Example: Counting incoming Spanish traffic (using smaller geoip map files) 151 | 152 | Use the `-c/--country-filter` parameter to generate the additional files: 153 | 154 | - `geoip-ipv4-interesting.nft` 155 | - `geoip-ipv6-interesting.nft` 156 | 157 | For this example the command might look like this (assuming dbip.csv is not 158 | present): 159 | 160 | ``` 161 | $ ./nft_geoip --download -c es 162 | ``` 163 | 164 | Create a file, `geoip.nft` (it will be at `/etc/geoip.nft` for this example) 165 | and use the "interesting" files not the whole geoip maps. 166 | ``` 167 | #!/usr/sbin/nft -f 168 | 169 | table inet geoip { 170 | include "geoip-def-all.nft" 171 | include "geoip-ipv4-interesting.nft" 172 | include "geoip-ipv6-interesting.nft" 173 | 174 | chain geoip-mark-input { 175 | type filter hook input priority -1; policy accept; 176 | 177 | meta mark set ip saddr map @geoip4 178 | meta mark set ip6 saddr map @geoip6 179 | } 180 | 181 | chain input { 182 | type filter hook input priority 0; policy accept; 183 | 184 | meta mark $ES counter 185 | } 186 | } 187 | ``` 188 | __NOTE:__ You can replace `geoip-def-all.nft` by `geoip-def-europe.nft`, or 189 | just copy the "define ES = ..." line into your nft file. 190 | 191 | 192 | # Caveats 193 | 194 | __It is not possible to use the country definitions inside an interactive 195 | nft shell.__ 196 | 197 | So, although maps are defined, country definitions do not persist. 198 | You will need to define those geoip rules inside your ruleset definition 199 | files. Like in the example above. 200 | 201 | __You will need ~300MB of free memory to run the script and also to load 202 | the full (all) ipv4 and ipv6 maps.__ 203 | 204 | It's been reported that low memory machines, (eg. GCP f1-micro) are not 205 | enough and the scripts ends up killed by the OOM-killer. 206 | 207 | This will be fixed in [#1](https://github.com/JMGuisadoG/nftables-geoip/issues/1). 208 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | You can try out an example by executing it (probably you will need `sudo`). 2 | Assuming nft is located at `/usr/sbin`. 3 | 4 | ``` 5 | sudo ./example.nft 6 | ``` 7 | 8 | You can specify an additional folder for `nft` to lookup for files with `-I` so you 9 | don't need to modify the includes. This should be the folder in which you saved the 10 | script output. 11 | 12 | ``` 13 | sudo ./example.nft [ -I path/to/script/output ] 14 | ``` 15 | -------------------------------------------------------------------------------- /examples/accounting.nft: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/nft -f 2 | 3 | # Accounting of incoming Spanish traffic, ipv4 and ipv6 4 | 5 | flush ruleset 6 | 7 | table inet filter { 8 | 9 | include "geoip-def-all.nft" 10 | include "geoip-ipv4.nft" 11 | include "geoip-ipv6.nft" 12 | 13 | chain geoip-mark-input { 14 | type filter hook input priority -1; policy accept; 15 | 16 | meta mark set ip saddr map @geoip4 17 | meta mark set ip6 saddr map @geoip6 18 | } 19 | 20 | chain input { 21 | type filter hook input priority filter; policy accept; 22 | 23 | mark $ES counter comment "incoming-ES" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /location.csv: -------------------------------------------------------------------------------- 1 | # Modified version of github.com/lukes/ISO-3166-Countries-with-Regional-Codes all.csv licensed under CC-BY-SA 4.0 2 | name,alpha-2,alpha-3,country-code,iso_3166-2,region,sub-region,intermediate-region,region-code,sub-region-code,intermediate-region-code 3 | Afghanistan,AF,AFG,004,ISO 3166-2:AF,Asia,Southern Asia,"",142,034,"" 4 | Åland Islands,AX,ALA,248,ISO 3166-2:AX,Europe,Northern Europe,"",150,154,"" 5 | Albania,AL,ALB,008,ISO 3166-2:AL,Europe,Southern Europe,"",150,039,"" 6 | Algeria,DZ,DZA,012,ISO 3166-2:DZ,Africa,Northern Africa,"",002,015,"" 7 | American Samoa,AS,ASM,016,ISO 3166-2:AS,Oceania,Polynesia,"",009,061,"" 8 | Andorra,AD,AND,020,ISO 3166-2:AD,Europe,Southern Europe,"",150,039,"" 9 | Angola,AO,AGO,024,ISO 3166-2:AO,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 10 | Anguilla,AI,AIA,660,ISO 3166-2:AI,Americas,Latin America and the Caribbean,Caribbean,019,419,029 11 | Antarctica,AQ,ATA,010,ISO 3166-2:AQ,"Antarctica","","","","","" 12 | Antigua and Barbuda,AG,ATG,028,ISO 3166-2:AG,Americas,Latin America and the Caribbean,Caribbean,019,419,029 13 | Argentina,AR,ARG,032,ISO 3166-2:AR,Americas,Latin America and the Caribbean,South America,019,419,005 14 | Armenia,AM,ARM,051,ISO 3166-2:AM,Asia,Western Asia,"",142,145,"" 15 | Aruba,AW,ABW,533,ISO 3166-2:AW,Americas,Latin America and the Caribbean,Caribbean,019,419,029 16 | Australia,AU,AUS,036,ISO 3166-2:AU,Oceania,Australia and New Zealand,"",009,053,"" 17 | Austria,AT,AUT,040,ISO 3166-2:AT,Europe,Western Europe,"",150,155,"" 18 | Azerbaijan,AZ,AZE,031,ISO 3166-2:AZ,Asia,Western Asia,"",142,145,"" 19 | Bahamas,BS,BHS,044,ISO 3166-2:BS,Americas,Latin America and the Caribbean,Caribbean,019,419,029 20 | Bahrain,BH,BHR,048,ISO 3166-2:BH,Asia,Western Asia,"",142,145,"" 21 | Bangladesh,BD,BGD,050,ISO 3166-2:BD,Asia,Southern Asia,"",142,034,"" 22 | Barbados,BB,BRB,052,ISO 3166-2:BB,Americas,Latin America and the Caribbean,Caribbean,019,419,029 23 | Belarus,BY,BLR,112,ISO 3166-2:BY,Europe,Eastern Europe,"",150,151,"" 24 | Belgium,BE,BEL,056,ISO 3166-2:BE,Europe,Western Europe,"",150,155,"" 25 | Belize,BZ,BLZ,084,ISO 3166-2:BZ,Americas,Latin America and the Caribbean,Central America,019,419,013 26 | Benin,BJ,BEN,204,ISO 3166-2:BJ,Africa,Sub-Saharan Africa,Western Africa,002,202,011 27 | Bermuda,BM,BMU,060,ISO 3166-2:BM,Americas,Northern America,"",019,021,"" 28 | Bhutan,BT,BTN,064,ISO 3166-2:BT,Asia,Southern Asia,"",142,034,"" 29 | Bolivia,BO,BOL,068,ISO 3166-2:BO,Americas,Latin America and the Caribbean,South America,019,419,005 30 | "Bonaire, Sint Eustatius and Saba",BQ,BES,535,ISO 3166-2:BQ,Americas,Latin America and the Caribbean,Caribbean,019,419,029 31 | Bosnia and Herzegovina,BA,BIH,070,ISO 3166-2:BA,Europe,Southern Europe,"",150,039,"" 32 | Botswana,BW,BWA,072,ISO 3166-2:BW,Africa,Sub-Saharan Africa,Southern Africa,002,202,018 33 | Bouvet Island,BV,BVT,074,ISO 3166-2:BV,Americas,Latin America and the Caribbean,South America,019,419,005 34 | Brazil,BR,BRA,076,ISO 3166-2:BR,Americas,Latin America and the Caribbean,South America,019,419,005 35 | British Indian Ocean Territory,IO,IOT,086,ISO 3166-2:IO,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 36 | Brunei Darussalam,BN,BRN,096,ISO 3166-2:BN,Asia,South-eastern Asia,"",142,035,"" 37 | Bulgaria,BG,BGR,100,ISO 3166-2:BG,Europe,Eastern Europe,"",150,151,"" 38 | Burkina Faso,BF,BFA,854,ISO 3166-2:BF,Africa,Sub-Saharan Africa,Western Africa,002,202,011 39 | Burundi,BI,BDI,108,ISO 3166-2:BI,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 40 | Cabo Verde,CV,CPV,132,ISO 3166-2:CV,Africa,Sub-Saharan Africa,Western Africa,002,202,011 41 | Cambodia,KH,KHM,116,ISO 3166-2:KH,Asia,South-eastern Asia,"",142,035,"" 42 | Cameroon,CM,CMR,120,ISO 3166-2:CM,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 43 | Canada,CA,CAN,124,ISO 3166-2:CA,Americas,Northern America,"",019,021,"" 44 | Cayman Islands,KY,CYM,136,ISO 3166-2:KY,Americas,Latin America and the Caribbean,Caribbean,019,419,029 45 | Central African Republic,CF,CAF,140,ISO 3166-2:CF,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 46 | Chad,TD,TCD,148,ISO 3166-2:TD,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 47 | Chile,CL,CHL,152,ISO 3166-2:CL,Americas,Latin America and the Caribbean,South America,019,419,005 48 | China,CN,CHN,156,ISO 3166-2:CN,Asia,Eastern Asia,"",142,030,"" 49 | Christmas Island,CX,CXR,162,ISO 3166-2:CX,Oceania,Australia and New Zealand,"",009,053,"" 50 | Cocos Keeling Islands,CC,CCK,166,ISO 3166-2:CC,Oceania,Australia and New Zealand,"",009,053,"" 51 | Colombia,CO,COL,170,ISO 3166-2:CO,Americas,Latin America and the Caribbean,South America,019,419,005 52 | Comoros,KM,COM,174,ISO 3166-2:KM,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 53 | Congo,CG,COG,178,ISO 3166-2:CG,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 54 | Democratic Republic of the Congo,CD,COD,180,ISO 3166-2:CD,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 55 | Cook Islands,CK,COK,184,ISO 3166-2:CK,Oceania,Polynesia,"",009,061,"" 56 | Costa Rica,CR,CRI,188,ISO 3166-2:CR,Americas,Latin America and the Caribbean,Central America,019,419,013 57 | Ivory Coast,CI,CIV,384,ISO 3166-2:CI,Africa,Sub-Saharan Africa,Western Africa,002,202,011 58 | Croatia,HR,HRV,191,ISO 3166-2:HR,Europe,Southern Europe,"",150,039,"" 59 | Cuba,CU,CUB,192,ISO 3166-2:CU,Americas,Latin America and the Caribbean,Caribbean,019,419,029 60 | Curaçao,CW,CUW,531,ISO 3166-2:CW,Americas,Latin America and the Caribbean,Caribbean,019,419,029 61 | Cyprus,CY,CYP,196,ISO 3166-2:CY,Asia,Western Asia,"",142,145,"" 62 | Czechia,CZ,CZE,203,ISO 3166-2:CZ,Europe,Eastern Europe,"",150,151,"" 63 | Denmark,DK,DNK,208,ISO 3166-2:DK,Europe,Northern Europe,"",150,154,"" 64 | Djibouti,DJ,DJI,262,ISO 3166-2:DJ,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 65 | Dominica,DM,DMA,212,ISO 3166-2:DM,Americas,Latin America and the Caribbean,Caribbean,019,419,029 66 | Dominican Republic,DO,DOM,214,ISO 3166-2:DO,Americas,Latin America and the Caribbean,Caribbean,019,419,029 67 | Ecuador,EC,ECU,218,ISO 3166-2:EC,Americas,Latin America and the Caribbean,South America,019,419,005 68 | Egypt,EG,EGY,818,ISO 3166-2:EG,Africa,Northern Africa,"",002,015,"" 69 | El Salvador,SV,SLV,222,ISO 3166-2:SV,Americas,Latin America and the Caribbean,Central America,019,419,013 70 | Equatorial Guinea,GQ,GNQ,226,ISO 3166-2:GQ,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 71 | Eritrea,ER,ERI,232,ISO 3166-2:ER,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 72 | Estonia,EE,EST,233,ISO 3166-2:EE,Europe,Northern Europe,"",150,154,"" 73 | Eswatini,SZ,SWZ,748,ISO 3166-2:SZ,Africa,Sub-Saharan Africa,Southern Africa,002,202,018 74 | Ethiopia,ET,ETH,231,ISO 3166-2:ET,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 75 | Falkland Islands,FK,FLK,238,ISO 3166-2:FK,Americas,Latin America and the Caribbean,South America,019,419,005 76 | Faroe Islands,FO,FRO,234,ISO 3166-2:FO,Europe,Northern Europe,"",150,154,"" 77 | Fiji,FJ,FJI,242,ISO 3166-2:FJ,Oceania,Melanesia,"",009,054,"" 78 | Finland,FI,FIN,246,ISO 3166-2:FI,Europe,Northern Europe,"",150,154,"" 79 | France,FR,FRA,250,ISO 3166-2:FR,Europe,Western Europe,"",150,155,"" 80 | French Guiana,GF,GUF,254,ISO 3166-2:GF,Americas,Latin America and the Caribbean,South America,019,419,005 81 | French Polynesia,PF,PYF,258,ISO 3166-2:PF,Oceania,Polynesia,"",009,061,"" 82 | French Southern Territories,TF,ATF,260,ISO 3166-2:TF,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 83 | Gabon,GA,GAB,266,ISO 3166-2:GA,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 84 | Gambia,GM,GMB,270,ISO 3166-2:GM,Africa,Sub-Saharan Africa,Western Africa,002,202,011 85 | Georgia,GE,GEO,268,ISO 3166-2:GE,Asia,Western Asia,"",142,145,"" 86 | Germany,DE,DEU,276,ISO 3166-2:DE,Europe,Western Europe,"",150,155,"" 87 | Ghana,GH,GHA,288,ISO 3166-2:GH,Africa,Sub-Saharan Africa,Western Africa,002,202,011 88 | Gibraltar,GI,GIB,292,ISO 3166-2:GI,Europe,Southern Europe,"",150,039,"" 89 | Greece,GR,GRC,300,ISO 3166-2:GR,Europe,Southern Europe,"",150,039,"" 90 | Greenland,GL,GRL,304,ISO 3166-2:GL,Americas,Northern America,"",019,021,"" 91 | Grenada,GD,GRD,308,ISO 3166-2:GD,Americas,Latin America and the Caribbean,Caribbean,019,419,029 92 | Guadeloupe,GP,GLP,312,ISO 3166-2:GP,Americas,Latin America and the Caribbean,Caribbean,019,419,029 93 | Guam,GU,GUM,316,ISO 3166-2:GU,Oceania,Micronesia,"",009,057,"" 94 | Guatemala,GT,GTM,320,ISO 3166-2:GT,Americas,Latin America and the Caribbean,Central America,019,419,013 95 | Guernsey,GG,GGY,831,ISO 3166-2:GG,Europe,Northern Europe,Channel Islands,150,154,830 96 | Guinea,GN,GIN,324,ISO 3166-2:GN,Africa,Sub-Saharan Africa,Western Africa,002,202,011 97 | Guinea-Bissau,GW,GNB,624,ISO 3166-2:GW,Africa,Sub-Saharan Africa,Western Africa,002,202,011 98 | Guyana,GY,GUY,328,ISO 3166-2:GY,Americas,Latin America and the Caribbean,South America,019,419,005 99 | Haiti,HT,HTI,332,ISO 3166-2:HT,Americas,Latin America and the Caribbean,Caribbean,019,419,029 100 | Heard Island and McDonald Islands,HM,HMD,334,ISO 3166-2:HM,Oceania,Australia and New Zealand,"",009,053,"" 101 | Holy See,VA,VAT,336,ISO 3166-2:VA,Europe,Southern Europe,"",150,039,"" 102 | Honduras,HN,HND,340,ISO 3166-2:HN,Americas,Latin America and the Caribbean,Central America,019,419,013 103 | Hong Kong,HK,HKG,344,ISO 3166-2:HK,Asia,Eastern Asia,"",142,030,"" 104 | Hungary,HU,HUN,348,ISO 3166-2:HU,Europe,Eastern Europe,"",150,151,"" 105 | Iceland,IS,ISL,352,ISO 3166-2:IS,Europe,Northern Europe,"",150,154,"" 106 | India,IN,IND,356,ISO 3166-2:IN,Asia,Southern Asia,"",142,034,"" 107 | Indonesia,ID,IDN,360,ISO 3166-2:ID,Asia,South-eastern Asia,"",142,035,"" 108 | Iran,IR,IRN,364,ISO 3166-2:IR,Asia,Southern Asia,"",142,034,"" 109 | Iraq,IQ,IRQ,368,ISO 3166-2:IQ,Asia,Western Asia,"",142,145,"" 110 | Ireland,IE,IRL,372,ISO 3166-2:IE,Europe,Northern Europe,"",150,154,"" 111 | Isle of Man,IM,IMN,833,ISO 3166-2:IM,Europe,Northern Europe,"",150,154,"" 112 | Israel,IL,ISR,376,ISO 3166-2:IL,Asia,Western Asia,"",142,145,"" 113 | Italy,IT,ITA,380,ISO 3166-2:IT,Europe,Southern Europe,"",150,039,"" 114 | Jamaica,JM,JAM,388,ISO 3166-2:JM,Americas,Latin America and the Caribbean,Caribbean,019,419,029 115 | Japan,JP,JPN,392,ISO 3166-2:JP,Asia,Eastern Asia,"",142,030,"" 116 | Jersey,JE,JEY,832,ISO 3166-2:JE,Europe,Northern Europe,Channel Islands,150,154,830 117 | Jordan,JO,JOR,400,ISO 3166-2:JO,Asia,Western Asia,"",142,145,"" 118 | Kazakhstan,KZ,KAZ,398,ISO 3166-2:KZ,Asia,Central Asia,"",142,143,"" 119 | Kenya,KE,KEN,404,ISO 3166-2:KE,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 120 | Kiribati,KI,KIR,296,ISO 3166-2:KI,Oceania,Micronesia,"",009,057,"" 121 | North Korea,KP,PRK,408,ISO 3166-2:KP,Asia,Eastern Asia,"",142,030,"" 122 | South Korea,KR,KOR,410,ISO 3166-2:KR,Asia,Eastern Asia,"",142,030,"" 123 | Kuwait,KW,KWT,414,ISO 3166-2:KW,Asia,Western Asia,"",142,145,"" 124 | Kyrgyzstan,KG,KGZ,417,ISO 3166-2:KG,Asia,Central Asia,"",142,143,"" 125 | Laos,LA,LAO,418,ISO 3166-2:LA,Asia,South-eastern Asia,"",142,035,"" 126 | Latvia,LV,LVA,428,ISO 3166-2:LV,Europe,Northern Europe,"",150,154,"" 127 | Lebanon,LB,LBN,422,ISO 3166-2:LB,Asia,Western Asia,"",142,145,"" 128 | Lesotho,LS,LSO,426,ISO 3166-2:LS,Africa,Sub-Saharan Africa,Southern Africa,002,202,018 129 | Liberia,LR,LBR,430,ISO 3166-2:LR,Africa,Sub-Saharan Africa,Western Africa,002,202,011 130 | Libya,LY,LBY,434,ISO 3166-2:LY,Africa,Northern Africa,"",002,015,"" 131 | Liechtenstein,LI,LIE,438,ISO 3166-2:LI,Europe,Western Europe,"",150,155,"" 132 | Lithuania,LT,LTU,440,ISO 3166-2:LT,Europe,Northern Europe,"",150,154,"" 133 | Luxembourg,LU,LUX,442,ISO 3166-2:LU,Europe,Western Europe,"",150,155,"" 134 | Macao,MO,MAC,446,ISO 3166-2:MO,Asia,Eastern Asia,"",142,030,"" 135 | Madagascar,MG,MDG,450,ISO 3166-2:MG,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 136 | Malawi,MW,MWI,454,ISO 3166-2:MW,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 137 | Malaysia,MY,MYS,458,ISO 3166-2:MY,Asia,South-eastern Asia,"",142,035,"" 138 | Maldives,MV,MDV,462,ISO 3166-2:MV,Asia,Southern Asia,"",142,034,"" 139 | Mali,ML,MLI,466,ISO 3166-2:ML,Africa,Sub-Saharan Africa,Western Africa,002,202,011 140 | Malta,MT,MLT,470,ISO 3166-2:MT,Europe,Southern Europe,"",150,039,"" 141 | Marshall Islands,MH,MHL,584,ISO 3166-2:MH,Oceania,Micronesia,"",009,057,"" 142 | Martinique,MQ,MTQ,474,ISO 3166-2:MQ,Americas,Latin America and the Caribbean,Caribbean,019,419,029 143 | Mauritania,MR,MRT,478,ISO 3166-2:MR,Africa,Sub-Saharan Africa,Western Africa,002,202,011 144 | Mauritius,MU,MUS,480,ISO 3166-2:MU,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 145 | Mayotte,YT,MYT,175,ISO 3166-2:YT,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 146 | Mexico,MX,MEX,484,ISO 3166-2:MX,Americas,Latin America and the Caribbean,Central America,019,419,013 147 | Federated States of Micronesia,FM,FSM,583,ISO 3166-2:FM,Oceania,Micronesia,"",009,057,"" 148 | Republic of Moldova,MD,MDA,498,ISO 3166-2:MD,Europe,Eastern Europe,"",150,151,"" 149 | Monaco,MC,MCO,492,ISO 3166-2:MC,Europe,Western Europe,"",150,155,"" 150 | Mongolia,MN,MNG,496,ISO 3166-2:MN,Asia,Eastern Asia,"",142,030,"" 151 | Montenegro,ME,MNE,499,ISO 3166-2:ME,Europe,Southern Europe,"",150,039,"" 152 | Montserrat,MS,MSR,500,ISO 3166-2:MS,Americas,Latin America and the Caribbean,Caribbean,019,419,029 153 | Morocco,MA,MAR,504,ISO 3166-2:MA,Africa,Northern Africa,"",002,015,"" 154 | Mozambique,MZ,MOZ,508,ISO 3166-2:MZ,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 155 | Myanmar,MM,MMR,104,ISO 3166-2:MM,Asia,South-eastern Asia,"",142,035,"" 156 | Namibia,NA,NAM,516,ISO 3166-2:NA,Africa,Sub-Saharan Africa,Southern Africa,002,202,018 157 | Nauru,NR,NRU,520,ISO 3166-2:NR,Oceania,Micronesia,"",009,057,"" 158 | Nepal,NP,NPL,524,ISO 3166-2:NP,Asia,Southern Asia,"",142,034,"" 159 | Netherlands,NL,NLD,528,ISO 3166-2:NL,Europe,Western Europe,"",150,155,"" 160 | New Caledonia,NC,NCL,540,ISO 3166-2:NC,Oceania,Melanesia,"",009,054,"" 161 | New Zealand,NZ,NZL,554,ISO 3166-2:NZ,Oceania,Australia and New Zealand,"",009,053,"" 162 | Nicaragua,NI,NIC,558,ISO 3166-2:NI,Americas,Latin America and the Caribbean,Central America,019,419,013 163 | Niger,NE,NER,562,ISO 3166-2:NE,Africa,Sub-Saharan Africa,Western Africa,002,202,011 164 | Nigeria,NG,NGA,566,ISO 3166-2:NG,Africa,Sub-Saharan Africa,Western Africa,002,202,011 165 | Niue,NU,NIU,570,ISO 3166-2:NU,Oceania,Polynesia,"",009,061,"" 166 | Norfolk Island,NF,NFK,574,ISO 3166-2:NF,Oceania,Australia and New Zealand,"",009,053,"" 167 | North Macedonia,MK,MKD,807,ISO 3166-2:MK,Europe,Southern Europe,"",150,039,"" 168 | Northern Mariana Islands,MP,MNP,580,ISO 3166-2:MP,Oceania,Micronesia,"",009,057,"" 169 | Norway,NO,NOR,578,ISO 3166-2:NO,Europe,Northern Europe,"",150,154,"" 170 | Oman,OM,OMN,512,ISO 3166-2:OM,Asia,Western Asia,"",142,145,"" 171 | Pakistan,PK,PAK,586,ISO 3166-2:PK,Asia,Southern Asia,"",142,034,"" 172 | Palau,PW,PLW,585,ISO 3166-2:PW,Oceania,Micronesia,"",009,057,"" 173 | Palestine,PS,PSE,275,ISO 3166-2:PS,Asia,Western Asia,"",142,145,"" 174 | Panama,PA,PAN,591,ISO 3166-2:PA,Americas,Latin America and the Caribbean,Central America,019,419,013 175 | Papua New Guinea,PG,PNG,598,ISO 3166-2:PG,Oceania,Melanesia,"",009,054,"" 176 | Paraguay,PY,PRY,600,ISO 3166-2:PY,Americas,Latin America and the Caribbean,South America,019,419,005 177 | Peru,PE,PER,604,ISO 3166-2:PE,Americas,Latin America and the Caribbean,South America,019,419,005 178 | Philippines,PH,PHL,608,ISO 3166-2:PH,Asia,South-eastern Asia,"",142,035,"" 179 | Pitcairn,PN,PCN,612,ISO 3166-2:PN,Oceania,Polynesia,"",009,061,"" 180 | Poland,PL,POL,616,ISO 3166-2:PL,Europe,Eastern Europe,"",150,151,"" 181 | Portugal,PT,PRT,620,ISO 3166-2:PT,Europe,Southern Europe,"",150,039,"" 182 | Puerto Rico,PR,PRI,630,ISO 3166-2:PR,Americas,Latin America and the Caribbean,Caribbean,019,419,029 183 | Qatar,QA,QAT,634,ISO 3166-2:QA,Asia,Western Asia,"",142,145,"" 184 | Réunion,RE,REU,638,ISO 3166-2:RE,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 185 | Romania,RO,ROU,642,ISO 3166-2:RO,Europe,Eastern Europe,"",150,151,"" 186 | Russian Federation,RU,RUS,643,ISO 3166-2:RU,Europe,Eastern Europe,"",150,151,"" 187 | Rwanda,RW,RWA,646,ISO 3166-2:RW,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 188 | Saint Barthélemy,BL,BLM,652,ISO 3166-2:BL,Americas,Latin America and the Caribbean,Caribbean,019,419,029 189 | Saint Helena,SH,SHN,654,ISO 3166-2:SH,Africa,Sub-Saharan Africa,Western Africa,002,202,011 190 | Saint Kitts and Nevis,KN,KNA,659,ISO 3166-2:KN,Americas,Latin America and the Caribbean,Caribbean,019,419,029 191 | Saint Lucia,LC,LCA,662,ISO 3166-2:LC,Americas,Latin America and the Caribbean,Caribbean,019,419,029 192 | Saint Martin,MF,MAF,663,ISO 3166-2:MF,Americas,Latin America and the Caribbean,Caribbean,019,419,029 193 | Saint Pierre and Miquelon,PM,SPM,666,ISO 3166-2:PM,Americas,Northern America,"",019,021,"" 194 | Saint Vincent and the Grenadines,VC,VCT,670,ISO 3166-2:VC,Americas,Latin America and the Caribbean,Caribbean,019,419,029 195 | Samoa,WS,WSM,882,ISO 3166-2:WS,Oceania,Polynesia,"",009,061,"" 196 | San Marino,SM,SMR,674,ISO 3166-2:SM,Europe,Southern Europe,"",150,039,"" 197 | Sao Tome and Principe,ST,STP,678,ISO 3166-2:ST,Africa,Sub-Saharan Africa,Middle Africa,002,202,017 198 | Saudi Arabia,SA,SAU,682,ISO 3166-2:SA,Asia,Western Asia,"",142,145,"" 199 | Senegal,SN,SEN,686,ISO 3166-2:SN,Africa,Sub-Saharan Africa,Western Africa,002,202,011 200 | Serbia,RS,SRB,688,ISO 3166-2:RS,Europe,Southern Europe,"",150,039,"" 201 | Seychelles,SC,SYC,690,ISO 3166-2:SC,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 202 | Sierra Leone,SL,SLE,694,ISO 3166-2:SL,Africa,Sub-Saharan Africa,Western Africa,002,202,011 203 | Singapore,SG,SGP,702,ISO 3166-2:SG,Asia,South-eastern Asia,"",142,035,"" 204 | Sint Maarten,SX,SXM,534,ISO 3166-2:SX,Americas,Latin America and the Caribbean,Caribbean,019,419,029 205 | Slovakia,SK,SVK,703,ISO 3166-2:SK,Europe,Eastern Europe,"",150,151,"" 206 | Slovenia,SI,SVN,705,ISO 3166-2:SI,Europe,Southern Europe,"",150,039,"" 207 | Solomon Islands,SB,SLB,090,ISO 3166-2:SB,Oceania,Melanesia,"",009,054,"" 208 | Somalia,SO,SOM,706,ISO 3166-2:SO,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 209 | South Africa,ZA,ZAF,710,ISO 3166-2:ZA,Africa,Sub-Saharan Africa,Southern Africa,002,202,018 210 | South Georgia and the South Sandwich Islands,GS,SGS,239,ISO 3166-2:GS,Americas,Latin America and the Caribbean,South America,019,419,005 211 | South Sudan,SS,SSD,728,ISO 3166-2:SS,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 212 | Spain,ES,ESP,724,ISO 3166-2:ES,Europe,Southern Europe,"",150,039,"" 213 | Sri Lanka,LK,LKA,144,ISO 3166-2:LK,Asia,Southern Asia,"",142,034,"" 214 | Sudan,SD,SDN,729,ISO 3166-2:SD,Africa,Northern Africa,"",002,015,"" 215 | Suriname,SR,SUR,740,ISO 3166-2:SR,Americas,Latin America and the Caribbean,South America,019,419,005 216 | Svalbard and Jan Mayen,SJ,SJM,744,ISO 3166-2:SJ,Europe,Northern Europe,"",150,154,"" 217 | Sweden,SE,SWE,752,ISO 3166-2:SE,Europe,Northern Europe,"",150,154,"" 218 | Switzerland,CH,CHE,756,ISO 3166-2:CH,Europe,Western Europe,"",150,155,"" 219 | Syrian Arab Republic,SY,SYR,760,ISO 3166-2:SY,Asia,Western Asia,"",142,145,"" 220 | Taiwan,TW,TWN,158,ISO 3166-2:TW,Asia,Eastern Asia,"",142,030,"" 221 | Tajikistan,TJ,TJK,762,ISO 3166-2:TJ,Asia,Central Asia,"",142,143,"" 222 | Tanzania,TZ,TZA,834,ISO 3166-2:TZ,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 223 | Thailand,TH,THA,764,ISO 3166-2:TH,Asia,South-eastern Asia,"",142,035,"" 224 | Timor-Leste,TL,TLS,626,ISO 3166-2:TL,Asia,South-eastern Asia,"",142,035,"" 225 | Togo,TG,TGO,768,ISO 3166-2:TG,Africa,Sub-Saharan Africa,Western Africa,002,202,011 226 | Tokelau,TK,TKL,772,ISO 3166-2:TK,Oceania,Polynesia,"",009,061,"" 227 | Tonga,TO,TON,776,ISO 3166-2:TO,Oceania,Polynesia,"",009,061,"" 228 | Trinidad and Tobago,TT,TTO,780,ISO 3166-2:TT,Americas,Latin America and the Caribbean,Caribbean,019,419,029 229 | Tunisia,TN,TUN,788,ISO 3166-2:TN,Africa,Northern Africa,"",002,015,"" 230 | Turkey,TR,TUR,792,ISO 3166-2:TR,Asia,Western Asia,"",142,145,"" 231 | Turkmenistan,TM,TKM,795,ISO 3166-2:TM,Asia,Central Asia,"",142,143,"" 232 | Turks and Caicos Islands,TC,TCA,796,ISO 3166-2:TC,Americas,Latin America and the Caribbean,Caribbean,019,419,029 233 | Tuvalu,TV,TUV,798,ISO 3166-2:TV,Oceania,Polynesia,"",009,061,"" 234 | Uganda,UG,UGA,800,ISO 3166-2:UG,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 235 | Ukraine,UA,UKR,804,ISO 3166-2:UA,Europe,Eastern Europe,"",150,151,"" 236 | United Arab Emirates,AE,ARE,784,ISO 3166-2:AE,Asia,Western Asia,"",142,145,"" 237 | United Kingdom,GB,GBR,826,ISO 3166-2:GB,Europe,Northern Europe,"",150,154,"" 238 | United States of America,US,USA,840,ISO 3166-2:US,Americas,Northern America,"",019,021,"" 239 | United States Minor Outlying Islands,UM,UMI,581,ISO 3166-2:UM,Oceania,Micronesia,"",009,057,"" 240 | Uruguay,UY,URY,858,ISO 3166-2:UY,Americas,Latin America and the Caribbean,South America,019,419,005 241 | Uzbekistan,UZ,UZB,860,ISO 3166-2:UZ,Asia,Central Asia,"",142,143,"" 242 | Vanuatu,VU,VUT,548,ISO 3166-2:VU,Oceania,Melanesia,"",009,054,"" 243 | Venezuela,VE,VEN,862,ISO 3166-2:VE,Americas,Latin America and the Caribbean,South America,019,419,005 244 | Viet Nam,VN,VNM,704,ISO 3166-2:VN,Asia,South-eastern Asia,"",142,035,"" 245 | Virgin Islands British,VG,VGB,092,ISO 3166-2:VG,Americas,Latin America and the Caribbean,Caribbean,019,419,029 246 | Virgin Islands US,VI,VIR,850,ISO 3166-2:VI,Americas,Latin America and the Caribbean,Caribbean,019,419,029 247 | Wallis and Futuna,WF,WLF,876,ISO 3166-2:WF,Oceania,Polynesia,"",009,061,"" 248 | Western Sahara,EH,ESH,732,ISO 3166-2:EH,Africa,Northern Africa,"",002,015,"" 249 | Yemen,YE,YEM,887,ISO 3166-2:YE,Asia,Western Asia,"",142,145,"" 250 | Zambia,ZM,ZMB,894,ISO 3166-2:ZM,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 251 | Zimbabwe,ZW,ZWE,716,ISO 3166-2:ZW,Africa,Sub-Saharan Africa,Eastern Africa,002,202,014 252 | -------------------------------------------------------------------------------- /nft_geoip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # (C) 2019 by Jose M. Guisado 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | 10 | """ 11 | Generate files containing nftables geoip mappings and definitions. 12 | 13 | This script is intended to be executed and not imported. 14 | """ 15 | 16 | from collections import namedtuple 17 | from datetime import datetime 18 | 19 | import argparse 20 | import csv 21 | import gzip 22 | import ipaddress 23 | import os 24 | import requests 25 | import shutil 26 | import sys 27 | import time 28 | import unicodedata 29 | 30 | DEFAULT_FILE_LOCATION = 'location.csv' 31 | DEFAULT_FILE_ADDRESS = 'dbip.csv' 32 | 33 | # entries in location csv 34 | GeoEntry = namedtuple('GeoEntry', 35 | 'name, ' 36 | 'alpha_2, ' 37 | 'alpha_3, ' 38 | 'country_code, ' 39 | 'iso_3166_2, ' 40 | 'region, ' 41 | 'sub_region, ' 42 | 'intermediate_region, ' 43 | 'region_code, ' 44 | 'sub_region_code, ' 45 | 'intermediate_region_code') 46 | 47 | # entries in DB-IP geoip csv 48 | NetworkEntry = namedtuple('NetworkEntry', 49 | 'network_first, ' 50 | 'network_last, ' 51 | 'country_alpha_2') 52 | 53 | 54 | class DownloadAction(argparse.BooleanOptionalAction): 55 | """ 56 | Custom BooleanOptionalAction to download db-ip csv in case the user 57 | specified so. 58 | """ 59 | def __call__(self, parser, namespace, values, option_string=None): 60 | super().__call__(parser, namespace, values, option_string=option_string) 61 | if namespace.download: 62 | filename = namespace.dir+'dbip.csv.gz' 63 | url = 'https://download.db-ip.com/free/dbip-country-lite-{}.csv.gz'.format(time.strftime("%Y-%m")) 64 | print('Downloading db-ip.com geoip csv file...') 65 | r = requests.get(url, stream=True) 66 | if r.status_code == 200: 67 | with open(filename, 'wb') as f: 68 | r.raw.decode_content = True 69 | shutil.copyfileobj(r.raw, f) 70 | else: 71 | sys.exit('Error trying to download DB-IP lite geoip csv file. Bailing out...') 72 | 73 | with gzip.open(filename, 'rb') as f_in: 74 | with open(namespace.dir+'dbip.csv', 'wb') as f_out: 75 | shutil.copyfileobj(f_in, f_out) 76 | os.remove(filename) 77 | # Update blocks arg with the downloaded file 78 | setattr(namespace, 'blocks', open(namespace.dir+'dbip.csv', 'r', encoding='utf-8')) 79 | 80 | def strip_accent(text): 81 | """ 82 | Remove accented characters. Convert to ASCII. 83 | """ 84 | return ''.join(char for char in unicodedata.normalize('NFKD', text) 85 | if unicodedata.category(char) != 'Mn') 86 | 87 | 88 | def make_location_dicts(): 89 | """ 90 | Returns three formatted dictionaries with following key/value: 91 | - iso_3166_2 (numeric) : country name 92 | - country_name : continent/region name 93 | - country_name : alpha2 name 94 | """ 95 | country_dict = {} 96 | continent_dict = {} 97 | country_alpha_dict = {} 98 | next(args.locations) # Omit license notice 99 | next(args.locations) # Omit csv header 100 | for geo_entry in map(GeoEntry._make, csv.reader(args.locations)): 101 | country_name = normalize(geo_entry.name) 102 | country_dict[normalize(geo_entry.country_code.lstrip('0'))] = country_name 103 | continent_dict[country_name] = normalize(geo_entry.region) 104 | country_alpha_dict[country_name] = normalize(geo_entry.alpha_2) 105 | return country_dict, continent_dict, country_alpha_dict 106 | 107 | 108 | def normalize(value): 109 | """ 110 | Strip accents and replace special characters. 111 | 112 | Used for keys and values inside location dictionaries. 113 | """ 114 | return strip_accent(value).lower().replace(' ', '_').replace('[', '').replace(']', '').replace(',', '') 115 | 116 | 117 | def write_geoip_location(country_dict, continent_dict, country_alpha_dict): 118 | """ 119 | Write country iso code definitions, separating files for each continent 120 | (eg. geoip-def-asia.nft, etc.) 121 | Also writes a definition file with all countries in "geoip-def-all.nft" 122 | """ 123 | for continent in continent_dict.values(): 124 | with open(args.dir+'geoip-def-{}.nft'.format(continent), 'w') as output_file: 125 | try: 126 | for country, iso in [(country, iso) 127 | for iso, country 128 | in country_dict.items() 129 | if continent_dict[country] == continent]: 130 | output_file.write('define {} = {}\n'.format(country_alpha_dict[country].upper(), iso)) 131 | except KeyError as e: 132 | # 'ZZ' is used for an unknown country, so it won't match 133 | # any country in the location file. Pass and do not write 134 | # to output file 135 | pass 136 | 137 | with open(args.dir+'geoip-def-all.nft', 'w') as output_file: 138 | for iso, country in country_dict.items(): 139 | output_file.write('define {} = {}\n'.format(country_alpha_dict[country].upper(), iso)) 140 | output_file.write('\n' * 2) 141 | 142 | output_file.write('define africa = 1\n' 143 | 'define asia = 2\n' 144 | 'define europe = 3\n' 145 | 'define americas = 4\n' 146 | 'define oceania = 5\n' 147 | 'define antarctica = 6\n') 148 | output_file.write('\n') 149 | output_file.write('map continent_code {\n' 150 | '\ttype mark : mark\n' 151 | '\tflags interval\n' 152 | '\telements = {\n\t\t') 153 | 154 | output_file.write(',\n\t\t'.join(make_lines2({country_alpha_dict[country].upper():v 155 | for country, v 156 | in continent_dict.items()}))) 157 | output_file.write('\n') 158 | output_file.write('\t}\n') 159 | output_file.write('}\n') 160 | 161 | 162 | def check_ipv4(addr): 163 | """ 164 | Returns true if a string is representing an ipv4 address. 165 | False otherwise. 166 | """ 167 | try: 168 | ipaddress.IPv4Address(addr) 169 | return True 170 | except ipaddress.AddressValueError: 171 | return False 172 | 173 | 174 | def make_geoip_dict(country_alpha_dict): 175 | """ 176 | Read DB-IP network ranges and creates geoip4 and geoip6 dictionaries 177 | mapping ip ranges over country alpha-2 codes 178 | """ 179 | # XXX: country_alpha_dict is used to prune countries not appearing 180 | # inside location.csv (eg. Kosovo) 181 | # 182 | # Kosovo could be added to location.csv with a "virtual" code 183 | # Kosovo,XK,XKX,999,ISO 3166-2:XK,Europe,"","","","","" 184 | # 185 | # Or instead use geonames. 186 | geoip4_dict = {} 187 | geoip6_dict = {} 188 | 189 | known_alphas = country_alpha_dict.values() 190 | 191 | # Reset file object position to start of the address file 192 | args.blocks.seek(0) 193 | 194 | for net_entry in map(NetworkEntry._make, csv.reader(args.blocks)): 195 | 196 | alpha2 = net_entry.country_alpha_2.lower() 197 | # 'ZZ' or codes not appearing in location.csv will be ignored 198 | if (alpha2 == 'zz') or (alpha2 not in known_alphas): 199 | continue 200 | 201 | # There are entries in DB-IP csv for single addresses which 202 | # are represented as same start and end address range. 203 | # nftables does not accept same start/end address in ranges 204 | if net_entry.network_first == net_entry.network_last: 205 | k = net_entry.network_first 206 | else: 207 | k = '-'.join((net_entry.network_first, net_entry.network_last)) 208 | 209 | if check_ipv4(net_entry.network_first): 210 | geoip4_dict[k] = alpha2 211 | else: 212 | geoip6_dict[k] = alpha2 213 | 214 | return geoip4_dict, geoip6_dict 215 | 216 | 217 | def make_lines1(dictionary): 218 | """ 219 | For each entry in the dictionary maps to a line for nftables dict files 220 | using key literal and value as nft variable. 221 | """ 222 | return ['{} : ${}'.format(k, v) for k, v in dictionary.items()] 223 | 224 | 225 | def make_lines2(dictionary): 226 | """ 227 | For each entry in the dictionary maps to a line for nftables dict files 228 | using key and value as nft variables. 229 | """ 230 | return ['${} : ${}'.format(k, v) for k, v in dictionary.items()] 231 | 232 | 233 | def write_nft_header(f): 234 | """ 235 | Writes nft comments about generation date and db-ip copyright notice. 236 | """ 237 | f.write("# Generated by nft_geoip.py on {}\n" 238 | .format(datetime.now().strftime("%a %b %d %H:%M %Y"))) 239 | f.write("# IP Geolocation by DB-IP (https://db-ip.com) licensed under CC-BY-SA 4.0\n\n") 240 | 241 | 242 | def write_geoip_maps(geoip4_dict, geoip6_dict, interesting=False): 243 | """ 244 | Write ipv4 and ipv6 geoip nftables maps to corresponding output files. 245 | """ 246 | ipv4_file = 'geoip-ipv4-interesting.nft' if interesting else 'geoip-ipv4.nft' 247 | ipv6_file = 'geoip-ipv6-interesting.nft' if interesting else 'geoip-ipv6.nft' 248 | with open(args.dir+ipv4_file, 'w') as output_file: 249 | write_nft_header(output_file) 250 | output_file.write('map geoip4 {\n' 251 | '\ttype ipv4_addr : mark\n' 252 | '\tflags interval\n' 253 | '\telements = {\n\t\t') 254 | 255 | output_file.write(',\n\t\t'.join(make_lines1({k:v.upper() for k,v in geoip4_dict.items()}))) 256 | output_file.write('\n') 257 | output_file.write('\t}\n') 258 | output_file.write('}\n') 259 | 260 | with open(args.dir+ipv6_file, 'w') as output_file: 261 | write_nft_header(output_file) 262 | output_file.write('map geoip6 {\n' 263 | '\ttype ipv6_addr : mark\n' 264 | '\tflags interval\n' 265 | '\telements = {\n\t\t') 266 | 267 | output_file.write(',\n\t\t'.join(make_lines1({k:v.upper() for k,v in geoip6_dict.items()}))) 268 | output_file.write('\n') 269 | output_file.write('\t}\n') 270 | output_file.write('}\n') 271 | 272 | 273 | def create_parser(): 274 | """ 275 | Returns cli argument parser 276 | """ 277 | parser = argparse.ArgumentParser(description=__doc__, 278 | prog='nft_geoip') 279 | parser.add_argument('--file-location', 280 | type=argparse.FileType('r'), 281 | help='path to csv file containing information about countries. ' 282 | f'(default: {DEFAULT_FILE_LOCATION})', 283 | default=DEFAULT_FILE_LOCATION, 284 | required=False, 285 | dest='locations') 286 | parser.add_argument('--file-address', 287 | type=argparse.FileType('r'), 288 | help='path to db-ip.com lite cvs file with ipv4 and ipv6 geoip information ' 289 | f'(default: {DEFAULT_FILE_ADDRESS})', 290 | required=False, 291 | dest='blocks') 292 | parser.add_argument('-d', '--download', action=DownloadAction, 293 | help='Fetch geoip data from db-ip.com. Overrides --file-address.', 294 | default=False, 295 | required=False) 296 | parser.add_argument('-o', '--output-dir', 297 | help='Existing directory where downloads and output will be saved. ' 298 | '(default: working directory)', 299 | default='./', 300 | required=False, 301 | dest='dir') 302 | parser.add_argument('-c', '--country-filter,', 303 | help='Comma-separated list of countries to create a filtered nft map (e.g. us,ca,gb). ' 304 | 'Accepts full name or abbrevation (see --show-countries)', 305 | required=False, 306 | dest='countries') 307 | parser.add_argument('--show-countries', action='store_true', 308 | help='Show a list of countries to be provided to --country-filter.', 309 | required=False) 310 | return parser 311 | 312 | 313 | if __name__ == '__main__': 314 | parser = create_parser() 315 | args = parser.parse_args() 316 | 317 | if not os.path.isdir(args.dir): 318 | parser.print_help() 319 | sys.exit('\nSpecified output directory does not exist or is not a directory') 320 | else: 321 | # Add trailing / for folder path if there isn't 322 | args.dir += '/' if args.dir[-1:] != '/' else '' 323 | 324 | if not (args.blocks or args.locations): 325 | parser.print_help() 326 | sys.exit('Missing required address and location csv files.') 327 | if not args.blocks: 328 | parser.print_help() 329 | sys.exit('Missing geoip address csv file. You can instead download it using --download.') 330 | if not args.locations: 331 | parser.print_help() 332 | sys.exit('Missing country information csv file') 333 | 334 | country_dict, continent_dict, country_alpha_dict = make_location_dicts() 335 | 336 | if args.show_countries: 337 | for k, v in country_alpha_dict.items(): 338 | print("Country: {} ({})".format(k,v)) 339 | sys.exit(0) 340 | 341 | print('Writing country definition files...') 342 | write_geoip_location(country_dict, continent_dict, country_alpha_dict) 343 | print('Writing nftables maps (geoip-ipv{4,6}.nft)...') 344 | geoip4_dict, geoip6_dict = make_geoip_dict(country_alpha_dict) 345 | write_geoip_maps(geoip4_dict, geoip6_dict) 346 | 347 | # Write separate map of countries if list provided 348 | if (args.countries): 349 | countries = list(map(str.lower,args.countries.split(','))) 350 | interesting_countries = {k: v for k, v in country_alpha_dict.items() if k in countries or v in countries} 351 | if len(interesting_countries) > 0: 352 | print('Found countries: ', interesting_countries) 353 | print('Writing interesting countries file...') 354 | interesting_countries_ipv4, interesting_countries_ipv6 = make_geoip_dict(interesting_countries) 355 | write_geoip_maps(interesting_countries_ipv4, interesting_countries_ipv6, True) 356 | else: 357 | print('Skipping interesting countries output, no matching countries found') 358 | 359 | print('Done!') 360 | --------------------------------------------------------------------------------