{"id":5664,"date":"2020-05-18T14:07:09","date_gmt":"2020-05-18T08:37:09","guid":{"rendered":"https:\/\/pheonixsolutions.com\/blog\/?p=5664"},"modified":"2026-11-12T11:09:13","modified_gmt":"2026-11-12T05:39:13","slug":"how-to-block-ips-via-htaccess-file","status":"publish","type":"post","link":"https:\/\/pheonixsolutions.com\/blog\/how-to-block-ips-via-htaccess-file\/","title":{"rendered":"How to block ips via .htaccess file ?"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Post Date:<\/strong> May 18, 2020<br><strong>Last Updated:<\/strong> November 12, 2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This guide explains how to <strong>block IPs via htaccess<\/strong> on an Apache web server. An <code>.htaccess<\/code> file lets you deny single IP addresses, whole ranges, or everyone except a trusted few. You can apply the rules to a whole site or to one folder, without editing the main Apache configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The original guide used the old <code>Order<\/code>, <code>Allow<\/code> and <code>Deny<\/code> directives from Apache 2.2. Those still work on Apache 2.4 only if a compatibility module is loaded. This version uses the current <code>Require<\/code> syntax and keeps the old syntax as a fallback. It also fixes the example IP <code>290.0.0.0<\/code>, which is invalid because no part of an IPv4 address can exceed 255. A lockout warning and troubleshooting section are new too.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Warning:<\/strong> When you block IPs via htaccess, a wrong rule can lock you out of your own site. Back up the file first, and keep your own IP in an allow list if you work on a restricted folder. A syntax error in <code>.htaccess<\/code> returns a 500 Internal Server Error for the whole directory.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before you block IPs via htaccess, make sure you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>File Manager, FTP or SSH access to the site&#8217;s folder<\/li>\n\n\n\n<li>Apache as the web server (LiteSpeed also reads <code>.htaccess<\/code>, but Nginx does not)<\/li>\n\n\n\n<li><code>AllowOverride All<\/code> (or at least <code>AllowOverride AuthConfig Limit<\/code>) set for the folder, otherwise Apache ignores the file<\/li>\n\n\n\n<li>The IP addresses you want to block, and your own IP so you don&#8217;t block yourself<\/li>\n\n\n\n<li>A backup copy of any existing <code>.htaccess<\/code> file<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A visitor&#8217;s request reaches Apache, which sees the visitor&#8217;s IP address<\/li>\n\n\n\n<li>Apache reads the <code>.htaccess<\/code> file in the requested folder and in each parent folder up to the document root<\/li>\n\n\n\n<li>The access rules compare the visitor&#8217;s IP with your <code>Require<\/code> lines (or the old <code>Allow<\/code> and <code>Deny<\/code> lines)<\/li>\n\n\n\n<li>A match on a blocked address returns 403 Forbidden, and any other visitor gets the page with 200 OK<\/li>\n\n\n\n<li>The <code>.htaccess<\/code> file in <code>public_html<\/code> covers the whole site, and one inside a subfolder covers only that folder<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The image below shows the workflow. For the official reference, see the Apache guide on <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/howto\/access.html\" target=\"_blank\" rel=\"noopener\">access control<\/a> and the <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/howto\/htaccess.html\" target=\"_blank\" rel=\"noopener\">.htaccess how-to<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic.png\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic-1024x576.png\" alt=\"\" class=\"wp-image-13206\" srcset=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic-1024x576.png 1024w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic-300x169.png 300w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic-768x432.png 768w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic-1536x864.png 1536w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/htaccess-IP-Blocking-Security-Infographic.png 1672w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Steps to Block IPs via htaccess on Apache<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Short answer:<\/strong> To block IPs via htaccess on Apache 2.4, open or create the <code>.htaccess<\/code> file, wrap <code>Require all granted<\/code> and one <code>Require not ip<\/code> line per address inside a <code>&lt;RequireAll&gt;<\/code> block, save the file, and test that a blocked IP gets a 403 error. On Apache 2.2, use <code>Order allow,deny<\/code> with <code>Deny from<\/code> lines.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Check Your Apache Version and Find the File<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">apachectl -v\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>.htaccess<\/code> is a hidden file because of the leading dot. Turn on &#8220;Show Hidden Files&#8221; in File Manager or your FTP program. If the file does not exist, create it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Whole site:<\/strong> put <code>.htaccess<\/code> in the <code>public_html<\/code> folder<\/li>\n\n\n\n<li><strong>One folder:<\/strong> put it inside that folder, for example <code>public_html\/dev<\/code> to protect <code>https:\/\/example.com\/dev<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Back up an existing file before editing:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cp .htaccess .htaccess.bak\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Block Specific IP Addresses (Apache 2.4)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the core step to block IPs via htaccess. Add one <code>Require not ip<\/code> line per address:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;RequireAll>\n    Require all granted\n    Require not ip 203.0.113.10\n    Require not ip 198.51.100.7\n&lt;\/RequireAll>\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The original examples used <code>290.0.0.0<\/code> and <code>111.111.1.1<\/code>. These examples use reserved documentation addresses, so replace them with the real IPs you want to block. To block more, add more <code>Require not ip<\/code> lines inside the block.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Block a Whole IP Range<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use CIDR notation or a partial address to block a range:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;RequireAll>\n    Require all granted\n    Require not ip 198.51.100.0\/24\n    Require not ip 203.0.113\n&lt;\/RequireAll>\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line blocks <code>198.51.100.0<\/code> to <code>198.51.100.255<\/code>. The second blocks every address starting with <code>203.0.113<\/code>. For IPv6, use the full address or a prefix such as <code>Require not ip 2001:db8::\/32<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Allow Only Specific IPs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To lock a folder so only you and your developers can open it, use <code>Require ip<\/code>. Everyone else is denied automatically:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Require ip 203.0.113.25\nRequire ip 198.51.100.0\/24\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5. Use the Old Syntax on Apache 2.2<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>apachectl -v<\/code> shows Apache 2.2, use the original directives:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Order allow,deny\nAllow from all\nDeny from 203.0.113.10\nDeny from 198.51.100.7\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To allow only certain IPs on Apache 2.2:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Order deny,allow\nDeny from all\nAllow from 203.0.113.25\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Apache 2.4, these lines work only if <code>mod_access_compat<\/code> is enabled. Don&#8217;t mix them with <code>Require<\/code> lines in the same file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">6. Test the Rules<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file, then check the result from a blocked IP:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">curl -I https:\/\/example.com\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A blocked visitor should receive <code>HTTP\/1.1 403 Forbidden<\/code>. Other visitors should still see <code>200 OK<\/code>. Apache reads <code>.htaccess<\/code> on every request, so you don&#8217;t need to restart it. If you can&#8217;t test from the blocked address, check the log:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">tail -f \/var\/log\/httpd\/error_log\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Debian and Ubuntu, the log is <code>\/var\/log\/apache2\/error.log<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you block IPs via htaccess and the rules do not work, check these:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>&#8220;500 Internal Server Error&#8221; after saving:<\/strong> The file has a syntax error. Restore <code>.htaccess.bak<\/code>, then re-add the rules one at a time<\/li>\n\n\n\n<li><strong>&#8220;Invalid command &#8216;Require&#8217;, perhaps misspelled or defined by a module not included in the server configuration&#8221;:<\/strong> The server runs Apache 2.2, so use the syntax in Step 5<\/li>\n\n\n\n<li><strong>&#8220;Order not allowed here&#8221; or &#8220;Allow not allowed here&#8221;:<\/strong> <code>AllowOverride<\/code> is too restrictive for the folder. Ask your host or set <code>AllowOverride All<\/code><\/li>\n\n\n\n<li><strong>&#8220;AH01797: client denied by server configuration&#8221;:<\/strong> This log line is normal and shows that a block is working<\/li>\n\n\n\n<li><strong>A blocked visitor can still open the site:<\/strong> You block IPs via htaccess but Apache sees the proxy&#8217;s address, not the visitor&#8217;s. This happens behind Cloudflare or a load balancer, so enable <code>mod_remoteip<\/code> or block the IP at the proxy<\/li>\n\n\n\n<li><strong>You blocked yourself:<\/strong> Remove the rule through FTP, File Manager or SSH, or restore the backup<\/li>\n\n\n\n<li><strong>The rules are ignored completely:<\/strong> The <code>.htaccess<\/code> file name has a typo, or <code>AllowOverride None<\/code> is set. Also confirm the file is in the correct folder<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To block IPs via htaccess, open the file in the right folder, add <code>Require not ip<\/code> lines inside a <code>&lt;RequireAll&gt;<\/code> block (or <code>Deny from<\/code> lines on Apache 2.2), and test with <code>curl<\/code>. Use <code>Require ip<\/code> to allow only trusted addresses. Back up the file before every change, and use valid IP addresses, since an invalid one such as <code>290.0.0.0<\/code> never matches.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently Asked Questions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I block IPs via htaccess on Nginx?<\/strong><br>No. Nginx does not read <code>.htaccess<\/code> files. Use <code>deny<\/code> and <code>allow<\/code> rules in the Nginx server configuration instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I block a whole country or a range of IPs?<\/strong><br>Use CIDR notation, for example <code>Require not ip 198.51.100.0\/24<\/code>. For a whole country, a firewall or a service such as Cloudflare is easier, because country ranges are very long and change often.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Does <code>.htaccess<\/code> blocking slow down my site?<\/strong><br>A few rules have almost no effect. Hundreds of lines are slower, because Apache reads the file on every request. For long lists, use a firewall such as <code>iptables<\/code> or <code>firewalld<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I use the <code>Order allow,deny<\/code> lines from older guides?<\/strong><br>They work on Apache 2.2, and on Apache 2.4 only with <code>mod_access_compat<\/code>. Use <code>Require<\/code> on Apache 2.4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Related Articles<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/setup-redirection-one-domain-another-domain-htaccess\/\" target=\"_blank\" rel=\"noreferrer noopener\">Setup redirection from one domain to another domain on .htaccess<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/htaccess-redirection-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to redirect a website using .htaccess<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Talk to Our Technology Experts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dealing with spam bots, brute-force attempts, or suspicious traffic on your website? Our team can set up IP blocking, firewall rules, and ongoing threat monitoring to keep your site protected through our <a href=\"https:\/\/pheonixsolutions.com\/security\/\">Security Services<\/a>.<br><br><a href=\"https:\/\/pheonixsolutions.com\/contact\">Connect with our technology experts.<\/a><\/p>\n\n\n\n<ol class=\"wp-block-list\"><\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Post Date: May 18, 2020Last Updated: November 12, 2026 Introduction This guide explains how to block IPs via htaccess on [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":13207,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_hide_featured_image":false,"_jetpack_featured_image_duplicate_dismissed":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1024],"tags":[365],"class_list":["post-5664","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security","tag-htaccess","psol-cat-security"],"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/phn2x7-1tm","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/How-to-Block-IPs-via-.htaccess.png","_links":{"self":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5664","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=5664"}],"version-history":[{"count":2,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5664\/revisions"}],"predecessor-version":[{"id":13209,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5664\/revisions\/13209"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media\/13207"}],"wp:attachment":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=5664"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=5664"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=5664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}