How-To: Secure Solr by IP Address

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How-To: Secure Solr by IP Address

david.w.smiley@gmail.com
I was just researching how to secure Solr by IP address and I finally
figured it out.  Perhaps this might go in the ref guide but I'd like to
share it here anyhow.  The scenario is where only "localhost" should have
full unfettered access to Solr, whereas everyone else (notably web clients)
can only access some whitelisted paths.  This setup is intended for a
single instance of Solr (not a member of a cluster); the particular config
below would probably need adaptations for a cluster of Solr instances.  The
technique here uses a utility with Jetty called IPAccessHandler --
http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/IPAccessHandler.html
For reasons I don't know (and I did search), it was recently deprecated and
there's another InetAccessHandler (not in Solr's current version of Jetty)
but it doesn't support constraints incorporating paths, so it's a
non-option for my needs.

First, Java must be told to insist on it's IPv4 stack. This is because
Jetty's IPAccessHandler simply doesn't support IPv6 IP matching; it throws
NPEs in my experience. In recent versions of Solr, this can be easily done
just by adding -Djava.net.preferIPv4Stack=true at the Solr start
invocation.  Alternatively put it into SOLR_OPTS perhaps in solr.in.sh.

Edit server/etc/jetty.xml, and replace the line
mentioning ContextHandlerCollection with this:

<New id="IPAccessHandler"
class="org.eclipse.jetty.server.handler.IPAccessHandler">
               <Set name="white">
                 <Array type="String">
                   <Item>127.0.0.1</Item>
                   <Item>-.-.-.-|/solr/techproducts/select</Item>
                 </Array>
               </Set>
               <Set name="whiteListByPath">false</Set>
               <Set name="handler">
                 <New id="Contexts"
class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
               </Set>
             </New>

This mechanism wraps ContextHandlerCollection (which ultimately serves
Solr) with this handler that adds the constraints.  These constraints above
allow localhost to do anything; other IP addresses can only access
/solr/techproducts/select.  That line could be duplicated for other
white-listed paths -- I recommend creating request handlers for your use,
possibly with invariants to further constraint what someone can do.

note: I originally tried inserting the IPAccessHandler in
server/contexts/solr-jetty-context.xml but found that there's a bug in
IPAccessHanlder that fails to consider when HttpServletRequest.getPathInfo
is null.  And it wound up letting everything through (if I recall).  But I
like it up in server.xml anyway as it intercepts everything

~ David

--
Lucene/Solr Search Committer, Consultant, Developer, Author, Speaker
LinkedIn: http://linkedin.com/in/davidwsmiley | Book:
http://www.solrenterprisesearchserver.com
GW
Reply | Threaded
Open this post in threaded view
|

Re: How-To: Secure Solr by IP Address

GW
I run a small solrcloud on a set of internal IP address. I connect with a
routed OpenVPN so I hit solr on 10.8.0.1:8983 from my desktop. Only my web
clients are on public IPs and only those clients can talk to the inside
cluster.

That's how I manage things...

On 4 November 2016 at 09:27, David Smiley <[hidden email]> wrote:

> I was just researching how to secure Solr by IP address and I finally
> figured it out.  Perhaps this might go in the ref guide but I'd like to
> share it here anyhow.  The scenario is where only "localhost" should have
> full unfettered access to Solr, whereas everyone else (notably web clients)
> can only access some whitelisted paths.  This setup is intended for a
> single instance of Solr (not a member of a cluster); the particular config
> below would probably need adaptations for a cluster of Solr instances.  The
> technique here uses a utility with Jetty called IPAccessHandler --
> http://download.eclipse.org/jetty/stable-9/apidocs/org/
> eclipse/jetty/server/handler/IPAccessHandler.html
> For reasons I don't know (and I did search), it was recently deprecated and
> there's another InetAccessHandler (not in Solr's current version of Jetty)
> but it doesn't support constraints incorporating paths, so it's a
> non-option for my needs.
>
> First, Java must be told to insist on it's IPv4 stack. This is because
> Jetty's IPAccessHandler simply doesn't support IPv6 IP matching; it throws
> NPEs in my experience. In recent versions of Solr, this can be easily done
> just by adding -Djava.net.preferIPv4Stack=true at the Solr start
> invocation.  Alternatively put it into SOLR_OPTS perhaps in solr.in.sh.
>
> Edit server/etc/jetty.xml, and replace the line
> mentioning ContextHandlerCollection with this:
>
> <New id="IPAccessHandler"
> class="org.eclipse.jetty.server.handler.IPAccessHandler">
>                <Set name="white">
>                  <Array type="String">
>                    <Item>127.0.0.1</Item>
>                    <Item>-.-.-.-|/solr/techproducts/select</Item>
>                  </Array>
>                </Set>
>                <Set name="whiteListByPath">false</Set>
>                <Set name="handler">
>                  <New id="Contexts"
> class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
>                </Set>
>              </New>
>
> This mechanism wraps ContextHandlerCollection (which ultimately serves
> Solr) with this handler that adds the constraints.  These constraints above
> allow localhost to do anything; other IP addresses can only access
> /solr/techproducts/select.  That line could be duplicated for other
> white-listed paths -- I recommend creating request handlers for your use,
> possibly with invariants to further constraint what someone can do.
>
> note: I originally tried inserting the IPAccessHandler in
> server/contexts/solr-jetty-context.xml but found that there's a bug in
> IPAccessHanlder that fails to consider when HttpServletRequest.getPathInfo
> is null.  And it wound up letting everything through (if I recall).  But I
> like it up in server.xml anyway as it intercepts everything
>
> ~ David
>
> --
> Lucene/Solr Search Committer, Consultant, Developer, Author, Speaker
> LinkedIn: http://linkedin.com/in/davidwsmiley | Book:
> http://www.solrenterprisesearchserver.com
>
Reply | Threaded
Open this post in threaded view
|

Re: How-To: Secure Solr by IP Address

john saylor
hi

any firewall worth it's name should be able to do this. in fact, that is
one of several things that a firewall was designed to do.

also, you are stopping this traffic at the application, which is good;
but you'd prolly be better off stopping it at the network interface
[using a firewall, for instance].

of course, firewalls have their own complexity ...

good luck!

Reply | Threaded
Open this post in threaded view
|

Re: How-To: Secure Solr by IP Address

david.w.smiley@gmail.com
Not to knock the other suggestions, but a benefit to securing Jetty like
this is that *everyone* can do this approach.

On Fri, Nov 4, 2016 at 9:54 AM john saylor <[hidden email]> wrote:

> hi
>
> any firewall worth it's name should be able to do this. in fact, that is
> one of several things that a firewall was designed to do.
>
> also, you are stopping this traffic at the application, which is good;
> but you'd prolly be better off stopping it at the network interface
> [using a firewall, for instance].
>
> of course, firewalls have their own complexity ...
>
> good luck!
>
> --
Lucene/Solr Search Committer, Consultant, Developer, Author, Speaker
LinkedIn: http://linkedin.com/in/davidwsmiley | Book:
http://www.solrenterprisesearchserver.com
Reply | Threaded
Open this post in threaded view
|

Re: How-To: Secure Solr by IP Address

Fuad Efendi
In reply to this post by david.w.smiley@gmail.com
Yes we need that documented,

http://stackoverflow.com/questions/8924102/restricting-ip-addresses-for-jetty-and-solr


Of course Firewall is a must for extremely strong environments / large corporations, DMZ, and etc; IPTables is the simplest solution if you run Linux; my vendor 1and1.com provides firewall functionality too - but I wouldn’t trust it: what if local at 1and1.com servers (in the same rack for example) can bypass this firewall?


Having option to configure Jetty minimizes dependencies. In real production I’d use all possible options: firewall(s) + iptable + Jetty config + DMZ(s)


--
Fuad Efendi
(416) 993-2060
http://www.tokenizer.ca
Search Relevancy, Recommender Systems


On November 4, 2016 at 9:28:21 AM, David Smiley ([hidden email]) wrote:

I was just researching how to secure Solr by IP address and I finally  
figured it out. Perhaps this might go in the ref guide but I'd like to  
share it here anyhow. The scenario is where only "localhost" should have  
full unfettered access to Solr, whereas everyone else (notably web clients)  
can only access some whitelisted paths. This setup is intended for a  
single instance of Solr (not a member of a cluster); the particular config  
below would probably need adaptations for a cluster of Solr instances. The  
technique here uses a utility with Jetty called IPAccessHandler --  
http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/IPAccessHandler.html 
For reasons I don't know (and I did search), it was recently deprecated and  
there's another InetAccessHandler (not in Solr's current version of Jetty)  
but it doesn't support constraints incorporating paths, so it's a  
non-option for my needs.  

First, Java must be told to insist on it's IPv4 stack. This is because  
Jetty's IPAccessHandler simply doesn't support IPv6 IP matching; it throws  
NPEs in my experience. In recent versions of Solr, this can be easily done  
just by adding -Djava.net.preferIPv4Stack=true at the Solr start  
invocation. Alternatively put it into SOLR_OPTS perhaps in solr.in.sh.  

Edit server/etc/jetty.xml, and replace the line  
mentioning ContextHandlerCollection with this:  

<New id="IPAccessHandler"  
class="org.eclipse.jetty.server.handler.IPAccessHandler">  
<Set name="white">  
<Array type="String">  
<Item>127.0.0.1</Item>  
<Item>-.-.-.-|/solr/techproducts/select</Item>  
</Array>  
</Set>  
<Set name="whiteListByPath">false</Set>  
<Set name="handler">  
<New id="Contexts"  
class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>  
</Set>  
</New>  

This mechanism wraps ContextHandlerCollection (which ultimately serves  
Solr) with this handler that adds the constraints. These constraints above  
allow localhost to do anything; other IP addresses can only access  
/solr/techproducts/select. That line could be duplicated for other  
white-listed paths -- I recommend creating request handlers for your use,  
possibly with invariants to further constraint what someone can do.  

note: I originally tried inserting the IPAccessHandler in  
server/contexts/solr-jetty-context.xml but found that there's a bug in  
IPAccessHanlder that fails to consider when HttpServletRequest.getPathInfo  
is null. And it wound up letting everything through (if I recall). But I  
like it up in server.xml anyway as it intercepts everything  

~ David  

--  
Lucene/Solr Search Committer, Consultant, Developer, Author, Speaker  
LinkedIn: http://linkedin.com/in/davidwsmiley | Book:  
http://www.solrenterprisesearchserver.com 
Reply | Threaded
Open this post in threaded view
|

Re: How-To: Secure Solr by IP Address

Fuad Efendi

*Deserves* to mention: I run Solr on 8080 port, and Firewall blocks *port* 8080. It is not indeed securing by IP address!

“block by IP” vs. “block by port number”

“block *all* services run on a machine by IP address” vs. “block only Jetty”

and etc.



Still need option for Jetty, it will simplify life ;)




On November 4, 2016 at 12:05:13 PM, Fuad Efendi ([hidden email]) wrote:

Yes we need that documented,

http://stackoverflow.com/questions/8924102/restricting-ip-addresses-for-jetty-and-solr


Of course Firewall is a must for extremely strong environments / large corporations, DMZ, and etc; IPTables is the simplest solution if you run Linux; my vendor 1and1.com provides firewall functionality too - but I wouldn’t trust it: what if local at 1and1.com servers (in the same rack for example) can bypass this firewall?


Having option to configure Jetty minimizes dependencies. In real production I’d use all possible options: firewall(s) + iptable + Jetty config + DMZ(s)


--
Fuad Efendi
(416) 993-2060
http://www.tokenizer.ca
Search Relevancy, Recommender Systems


On November 4, 2016 at 9:28:21 AM, David Smiley ([hidden email]) wrote:

I was just researching how to secure Solr by IP address and I finally
figured it out. Perhaps this might go in the ref guide but I'd like to
share it here anyhow. The scenario is where only "localhost" should have
full unfettered access to Solr, whereas everyone else (notably web clients)
can only access some whitelisted paths. This setup is intended for a
single instance of Solr (not a member of a cluster); the particular config
below would probably need adaptations for a cluster of Solr instances. The
technique here uses a utility with Jetty called IPAccessHandler --
http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/handler/IPAccessHandler.html
For reasons I don't know (and I did search), it was recently deprecated and
there's another InetAccessHandler (not in Solr's current version of Jetty)
but it doesn't support constraints incorporating paths, so it's a
non-option for my needs.

First, Java must be told to insist on it's IPv4 stack. This is because
Jetty's IPAccessHandler simply doesn't support IPv6 IP matching; it throws
NPEs in my experience. In recent versions of Solr, this can be easily done
just by adding -Djava.net.preferIPv4Stack=true at the Solr start
invocation. Alternatively put it into SOLR_OPTS perhaps in solr.in.sh.

Edit server/etc/jetty.xml, and replace the line
mentioning ContextHandlerCollection with this:

<New id="IPAccessHandler"
class="org.eclipse.jetty.server.handler.IPAccessHandler">
<Set name="white">
<Array type="String">
<Item>127.0.0.1</Item>
<Item>-.-.-.-|/solr/techproducts/select</Item>
</Array>
</Set>
<Set name="whiteListByPath">false</Set>
<Set name="handler">
<New id="Contexts"
class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Set>
</New>

This mechanism wraps ContextHandlerCollection (which ultimately serves
Solr) with this handler that adds the constraints. These constraints above
allow localhost to do anything; other IP addresses can only access
/solr/techproducts/select. That line could be duplicated for other
white-listed paths -- I recommend creating request handlers for your use,
possibly with invariants to further constraint what someone can do.

note: I originally tried inserting the IPAccessHandler in
server/contexts/solr-jetty-context.xml but found that there's a bug in
IPAccessHanlder that fails to consider when HttpServletRequest.getPathInfo
is null. And it wound up letting everything through (if I recall). But I
like it up in server.xml anyway as it intercepts everything

~ David

--
Lucene/Solr Search Committer, Consultant, Developer, Author, Speaker
LinkedIn: http://linkedin.com/in/davidwsmiley | Book:
http://www.solrenterprisesearchserver.com