{"id":915,"date":"2015-06-08T22:45:47","date_gmt":"2015-06-08T22:45:47","guid":{"rendered":"https:\/\/www.hort.net\/techblog\/?p=229"},"modified":"2015-06-08T22:45:47","modified_gmt":"2015-06-08T22:45:47","slug":"tightening-up-security-by-country","status":"publish","type":"post","link":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/","title":{"rendered":"Tightening up security, restricting by country"},"content":{"rendered":"<p>Lately we&#8217;ve noticed that more and more traffic to our servers involves attempted brute-force logins.  That means that a remote computer is connecting to our server and trying to guess usernames and passwords, with different variations of both, and hoping they&#8217;ll get in.  <\/p>\n<p>Things got to the point where we were seeing hundreds of thousands of login attempts daily for accounts like &#8216;admin&#8217;, &#8216;hortnet&#8217;, &#8216;wordpress&#8217;, variations of my name, and so on.  That&#8217;s crazy!  The attacks were also coming in bursts, so there might be a 30-second lull followed by thirty attempts within a few seconds.  We weren&#8217;t overly concerned because we have other protections in place like two-factor authentication, but there were so many failed logins that our server performance was starting to suffer.<\/p>\n<p>The first thing we did is what everyone else does: install software that blocks multiple failed attempts.  <a href=\"http:\/\/www.ossec.netc\" target=\"_blank\" rel=\"noopener noreferrer\">OSSEC<\/a> is great for that, but it only catches people after they&#8217;ve jiggled the door handle a few times.  Even with OSSEC installed we were still seeing 50,000 attempts daily.<\/p>\n<p>After studying the logs, a commonality became apparent.  Almost all of the attacks were coming from other countries.  Russia and China were the worst offenders, but just about every country around the globe was represented.  What if we could limit administrative access only to computers based in the US?  Nobody outside of the US needs to get in, and <a href=\"https:\/\/www.maxmind.com\" target=\"_blank\" rel=\"noopener noreferrer\">MaxMind<\/a> maintains a database of IP to country code mappings that would work perfectly.  Fortunately, they&#8217;re gracious enough to share a free version that will meet our needs.<\/p>\n<p>We crafted some scripts and discovered that limiting access from only US systems reduced login attempts by 99.9 percent.<\/p>\n<p>The first thing we did was install ipset on our server and configure the system to use it and our scripts (this is RedHat\/CentOS-centric).  Cut and paste the section below into your shell.<\/p>\n<div class=\"horttech-code\">\n<pre class=\"preserve-code-formatting\">\nsh -c &quot;PERL_MM_USE_DEFAULT=1 perl -MCPAN -e &#039;install Net::CIDR&#039;&quot;\nyum install -y ipset perl-Net-CIDR perl-libwww-perl\necho &quot;create -exist US hash:net family inet hashsize 2048 maxelem 65536&quot; &gt;&gt; \/etc\/sysconfig\/ipset\nmkdir -p \/var\/cache\/ipset\nmkdir -p \/usr\/services\/GeoIP\necho &quot;ipset restore &lt; \/var\/cache\/ipset\/us.conf&quot; &gt;&gt; \/etc\/rc.local\necho &quot;15 12 * * 2 root \/usr\/services\/GeoIP\/createUSipset&quot; &gt;&gt; \/etc\/cron.d\/ipset\n\/etc\/rc.d\/init.d\/ipset start\n<\/pre>\n<\/div>\n<p>This creates a set named &#8216;US&#8217; in ipset that will store the IP ranges of all known US IPs.  Note that the actual population of the set is done via \/etc\/rc.local &mdash; this is because \/etc\/sysconfig\/ipset can&#8217;t contain a &#8216;restore&#8217; command.  We could store all of our IPs directly in \/etc\/sysconfig\/ipset, but if you want to use ipset for anything different it becomes complicated.  Also, note that our cron entry only downloads on Tuesday because that&#8217;s the day that MaxMind releases database changes.<\/p>\n<p>Anyhow, once the stuff above is done, paste the section below into your shell to create the script that downloads the database.<\/p>\n<div class=\"horttech-code\">\n<pre class=\"preserve-code-formatting\">\ncat &lt;&lt;&#039;EOF&#039; &gt; \/usr\/services\/GeoIP\/createUSipset\n#!\/usr\/bin\/perl\n\nuse Net::CIDR;\nuse LWP::UserAgent;\nuse v5.10;\n$|++;\n\nmy $ua&nbsp;&nbsp;&nbsp;&nbsp;= LWP::UserAgent-&gt;new;\nmy $dir&nbsp;&nbsp; = qq(\/usr\/services\/GeoIP);\nmy $file&nbsp;&nbsp;= qq(GeoIPCountryCSV.zip);\nmy $url&nbsp;&nbsp; = qq(https:\/\/geolite.maxmind.com\/download\/geoip\/database\/$file);\nmy $cache = qq(\/var\/cache\/ipset\/us.conf);\n\nexit if ! ($ua-&gt;mirror($url, qq($dir\/$file)))-&gt;is_success;\n\nopen (IPSET, &quot;|ipset restore&quot;);\nsay IPSET qq(create -exist US-new hash:net family inet);\nopen (COUNTRY, &quot;zcat $dir\/$file|&quot;);\nwhile (&lt;COUNTRY&gt;) {\n&nbsp;&nbsp; next if $_ !~ \/&quot;US&quot;\/;\n&nbsp;&nbsp; my ($ipstart, $ipend) = ($_ =~ \/^&quot;([^&quot;]+)&quot;,&quot;([^&quot;]+)&quot;,\/);\n&nbsp;&nbsp; foreach my $i (Net::CIDR::range2cidr($ipstart .&nbsp;&nbsp;&quot;-&quot; .&nbsp;&nbsp;$ipend)) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say IPSET qq(add US-new $i);\n&nbsp;&nbsp; }\n}\nclose COUNTRY;\nclose IPSET;\n\nsystem qq(ipset swap US US-new);\nsystem qq(ipset save US | sed &#039;s\/create US\/create -exist US\/&#039; &gt; $cache);\nsystem qq(ipset destroy US-new);\nEOF\n\nchmod ug+rx \/usr\/services\/GeoIP\/createUSipset\n\/usr\/services\/GeoIP\/createUSipset\n<\/pre>\n<\/div>\n<p>Now you have a set populated with US IP addresses &mdash; all we have left is to actually use it with our iptables rules.  Here&#8217;s an example that blocks all non-US traffic to ssh, then saves the changes for a reboot:<\/p>\n<div class=\"horttech-code\">\n<pre class=\"preserve-code-formatting\">\n# BE CAREFUL RUNNING THIS, AND ONLY DO IT IF YOU UNDERSTAND WHAT YOU&#039;RE DOING\niptables -A INPUT -m set --set US src -p tcp -m tcp --dport 22 -j ACCEPT\niptables -A INPUT -p tcp -m tcp --dport 22 -j DROP\niptables-save\n<\/pre>\n<\/div>\n<p>The critical part above is the &#8216;-m set &#8211;set US&#8217; bit; it tells iptables to compare the connecting IP against the set contained within ipset.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lately we&#8217;ve noticed that more and more traffic to our servers involves attempted brute-force logins. That means that a remote computer is connecting to our server and trying to guess usernames and passwords, with different variations of both, and hoping they&#8217;ll get in. Things got to the point where we were seeing hundreds of thousands [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[62,66,67,75],"class_list":["post-915","post","type-post","status-publish","format-standard","hentry","category-security","tag-country","tag-ipset","tag-iptables","tag-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Tightening up security, restricting by country - hort.net blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tightening up security, restricting by country - hort.net blog\" \/>\n<meta property=\"og:description\" content=\"Lately we&#8217;ve noticed that more and more traffic to our servers involves attempted brute-force logins. That means that a remote computer is connecting to our server and trying to guess usernames and passwords, with different variations of both, and hoping they&#8217;ll get in. Things got to the point where we were seeing hundreds of thousands [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/\" \/>\n<meta property=\"og:site_name\" content=\"hort.net blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-06-08T22:45:47+00:00\" \/>\n<meta name=\"author\" content=\"Christopher Lindsey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Christopher Lindsey\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/\"},\"author\":{\"name\":\"Christopher Lindsey\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/#\\\/schema\\\/person\\\/c5048c118466b10e17155d29454e63de\"},\"headline\":\"Tightening up security, restricting by country\",\"datePublished\":\"2015-06-08T22:45:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/\"},\"wordCount\":493,\"commentCount\":0,\"keywords\":[\"country\",\"ipset\",\"iptables\",\"security\"],\"articleSection\":[\"security\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/\",\"url\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/\",\"name\":\"Tightening up security, restricting by country - hort.net blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/#website\"},\"datePublished\":\"2015-06-08T22:45:47+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/#\\\/schema\\\/person\\\/c5048c118466b10e17155d29454e63de\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/2015\\\/06\\\/08\\\/tightening-up-security-by-country\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tightening up security, restricting by country\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/\",\"name\":\"hort.net blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/#\\\/schema\\\/person\\\/c5048c118466b10e17155d29454e63de\",\"name\":\"Christopher Lindsey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/Christopher-Lindsey_avatar_1437067426-96x96.jpg\",\"url\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/Christopher-Lindsey_avatar_1437067426-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/Christopher-Lindsey_avatar_1437067426-96x96.jpg\",\"caption\":\"Christopher Lindsey\"},\"url\":\"https:\\\/\\\/www.hort.net\\\/blog\\\/author\\\/chris\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tightening up security, restricting by country - hort.net blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/","og_locale":"en_US","og_type":"article","og_title":"Tightening up security, restricting by country - hort.net blog","og_description":"Lately we&#8217;ve noticed that more and more traffic to our servers involves attempted brute-force logins. That means that a remote computer is connecting to our server and trying to guess usernames and passwords, with different variations of both, and hoping they&#8217;ll get in. Things got to the point where we were seeing hundreds of thousands [&hellip;]","og_url":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/","og_site_name":"hort.net blog","article_published_time":"2015-06-08T22:45:47+00:00","author":"Christopher Lindsey","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Christopher Lindsey","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/#article","isPartOf":{"@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/"},"author":{"name":"Christopher Lindsey","@id":"https:\/\/www.hort.net\/blog\/#\/schema\/person\/c5048c118466b10e17155d29454e63de"},"headline":"Tightening up security, restricting by country","datePublished":"2015-06-08T22:45:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/"},"wordCount":493,"commentCount":0,"keywords":["country","ipset","iptables","security"],"articleSection":["security"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/","url":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/","name":"Tightening up security, restricting by country - hort.net blog","isPartOf":{"@id":"https:\/\/www.hort.net\/blog\/#website"},"datePublished":"2015-06-08T22:45:47+00:00","author":{"@id":"https:\/\/www.hort.net\/blog\/#\/schema\/person\/c5048c118466b10e17155d29454e63de"},"breadcrumb":{"@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.hort.net\/blog\/2015\/06\/08\/tightening-up-security-by-country\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.hort.net\/blog\/"},{"@type":"ListItem","position":2,"name":"Tightening up security, restricting by country"}]},{"@type":"WebSite","@id":"https:\/\/www.hort.net\/blog\/#website","url":"https:\/\/www.hort.net\/blog\/","name":"hort.net blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.hort.net\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.hort.net\/blog\/#\/schema\/person\/c5048c118466b10e17155d29454e63de","name":"Christopher Lindsey","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.hort.net\/blog\/wp-content\/uploads\/2015\/07\/Christopher-Lindsey_avatar_1437067426-96x96.jpg","url":"https:\/\/www.hort.net\/blog\/wp-content\/uploads\/2015\/07\/Christopher-Lindsey_avatar_1437067426-96x96.jpg","contentUrl":"https:\/\/www.hort.net\/blog\/wp-content\/uploads\/2015\/07\/Christopher-Lindsey_avatar_1437067426-96x96.jpg","caption":"Christopher Lindsey"},"url":"https:\/\/www.hort.net\/blog\/author\/chris\/"}]}},"_links":{"self":[{"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/posts\/915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/comments?post=915"}],"version-history":[{"count":0,"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/posts\/915\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/media?parent=915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/categories?post=915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hort.net\/blog\/wp-json\/wp\/v2\/tags?post=915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}