Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Access control on committer IP?

Hanxi Zhang October 9, 2014

I would like to do access control based on committer's IP. I.e., allow pushing from development IPs and deny pushing from staging/production IPs. I am using Git Essentials/Git Stash and my git pushes are via the ssh protocol.

Without finding a better approach with Git Stash, I am trying to add a pre-receive hook (perl script) suggested by the following:

http://search.cpan.org/~mschilli/SVN-Utils-ClientIP-0.02/ClientIP.pm

Since it is based on lsof I have to run stash as root by setting the STASH_USER variable as root, which is not good from security stand point. Long story short, I got the pre-receive perl script to detect committer's IP correctly on a plain Git server, but in the Git Essential context, the script is not able to detect IP, likely due to the difference in inter-process mechanisms.

Is there better approaches and plugins that allows one to do IP-based access control?

Thank you very much for your comments.

 

 

3 answers

1 accepted

0 votes
Answer accepted
Michael Heemskerk
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 24, 2014

The best way to intercept hosting operations is through the use of  an ScmRequestCheck. You could

  • add a component-import in your atlassian-plugin.xml for RequestManager
  • define the scm-request-check module in your atlassian-plugin.xml
  • inject RequestManager in the constructor of your ScmRequestCheck
  • in check, call requestManager.getRequestContext().getRemoteAddress() to get the callers IP

I've created a small plugin to help you on your way: https://bitbucket.org/mheemskerk/stash-scm-ip-check-example

 

Hanxi Zhang October 29, 2014

Thank you so much Michale. It's working as a charm -- exactly the way I want it to be! -- Hanxi

0 votes
Michael Heemskerk
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 18, 2014

Edit: this solution does not work because the request context isn't available in a repository hook. See the other answer for an alternative.

 

An alternative is to write a small plugin that provides a PreReceiveRepositoryHook that checks the remote IP and allows or rejects the push.

  • add a component-import in your atlassian-plugin.xml for RequestManager
  • inject RequestManager in the constructor of your PreReceiveRepositoryHook
  • in onReceive, call requestManager.getRequestContext().getRemoteAddress() to get the callers IP.

Please note that if you have a proxy server in the mix and that proxy server sets X-Forwarded-For headers, the remote address may be a comma separated list of ip addresses. In that case, you'd want the first IP in the list.

Hanxi Zhang October 24, 2014

Hi Michael, I like the solution you suggested very much, however I am fighting a classloading issue: In my atlassian-plugin.xml I have: <component-import key="reqManager" interface="com.atlassian.stash.request.RequestManager" /> And my custom RepositoryHook looks like: public class MyRepositoryHook implements PreReceiveRepositoryHook { private com.atlassian.stash.request.RequestManager reqManager; public MyRepositoryHook(RequestManager reqManager) { this.reqManager = reqManager; } public boolean onReceive(...) { String ip = this.reqManager.getRequestContext().getRemoteAddress(); //do some ip checking and return true/false accordingly return true; } } I don't know if the above is the correct way to inject RequestManger to the PreReceiveHook. In my case upon a test push, the plugin throws null pointer exceptions because reqManager is null, which tells me it's not injected properly. The small custom plugin installs correctly and shows up in the "manage add-ons" admin page, with all modules loaded including the PreReceiveHook and the component-import for Request Manager. Thanks again for your comments!

Michael Heemskerk
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 24, 2014

Hi, The problem isn't that the RequestManager isn't being injected. The problem is that there is no current request context because the hooks get processed on a separate thread which doesn't inherit the request context state. There is an alternative however using `ScmRequestCheck`. I'll write a separate answer describing that option.

0 votes
Richard Bywater
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 9, 2014

Presumably if you want the staging/production machines to only be able to pull, you could add the SSH key for those machines in as Read Only Access tokens which would mean that they'd be able to pull and not push?

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events