Read only access to svn repository via ssh (svn+ssh) - linux

We desire to make subversion repositories read only. Doing this for a single repository in a subversion instance did not work regarding ssh. ssh access appears to bypass the controls of svn.
Followed the suggestions here:
Read-only access of Subversion repository
Write access should be restricted but that did not happen.
The repository is still write accessible despite changes to the repository for read only.

The easiest way to restrict access (assuming there are no users who require write access) is to remove the w (write) bit on the files in the SVN repo.
chmod -R gou-w /path/to/svn-repo
That will prevent writes at the filesystem / OS level.
If some users still require access, you can create separate svn+ssh endpoints for each user class that map to different users on the host server, using group write vs other write bits to determine which group has access to affect writes:
mkgrp writers-grp
chgrp -R writers-grp /path/to/svn-repo
chmod ug+w /path/to/svn-repo
chmod o-w /path/to/svn-repo
I would then register the SSH keys for writers against the writing user on the server, and prevent password access.
The "read-only" users could be allowed a well-known password.
This isn't as "clever" or "elegant" as configuring the SVN server configs, but it works pretty darned well as long as the users keep their SSH keys secret.

Restrict commit access with a start-commit hook.
Description
The start-commit hook is run before the commit transaction is even
created. It is typically used to decide whether the user has commit
privileges at all.
If the start-commit hook program returns a nonzero exit value, the
commit is stopped before the commit transaction is even created, and
anything printed to stderr is marshalled back to the client.
Input Parameter(s)
The command-line arguments passed to the hook program, in order, are:
Repository path
Authenticated username attempting the commit
Colon-separated list of capabilities that a client passes to the server, including depth, mergeinfo, and log-revprops (new in
Subversion 1.5).
Common uses
Access control (e.g., temporarily lock out commits for some reason).
A means to allow access only from clients that have certain
capabilities.

Related

Modifying the gitolite repository url

I have gitolite installed. I'm able to administer it fine. I've added a few new repos, and a few pub keys. Installed as 'git#domain.com' and a repo added for a user as repo.git.
Does it have to be git#domain.com:repo.git to access, or is there a way to indicate the user in the url?
Possibly something like user#domain.com:repo.git or git.domain.com/user/repo.git for example?
No, it has to be git#domain.com because the user is always the same: the git account you are using to install and administer gitolite on your server.
The actual user is deduced from the public key you are using when making your ssh call.
If you registered that key with the user.pub file representing said public key named after the user's login, then gitolite will be able to identify you.
For more, see "how gitolite uses ssh".
If you look in the authorized_keys file, you'll see entries like this (I chopped off the ends of course; they're pretty long lines):
command="[path]/gitolite-shell sitaram",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA18S2t...
command="[path]/gitolite-shell usertwo",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArXtCT...
First, it finds out which of the public keys in this file match the incoming login.
Once the match has been found, it will run the command given on that line; e.g., if I logged in, it would run [path]/gitolite-shell sitaram.
So the first thing to note is that such users do not get "shell access", which is good!
When gitolite-shell gets control, it looks at the first argument ("sitaram", "usertwo", etc) to determine who you are. It then looks at the SSH_ORIGINAL_COMMAND variable to find out which repository you want to access, and whether you're reading or writing.
Now that it has a user, repository, and access requested (read/write), gitolite looks at its config file, and either allows or rejects the request.

How to make git not ask for password at pull?

I have the following setup:
A server (centOS) with git and a repository for a project on the same server.
What I need to do is to be able to pull from the repository without being asked for password (because is annoying).
Note: I am logged as root when I pull.
Can anyone help me with that?
There are a few options, depending on what your requirements are, in particular your security needs. For both HTTP and SSH, there is password-less, or password required access.
HTTP
==============
Password-Less
Useful for fetch only requirements, by default push is disabled. Perfect if anonymous cloning is the intention. You definitely shouldn't enable push for this type of configuration. The man page for git-http-backend contains good information, online copy at http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html. It provides an example of how to configure apache to provide this.
User/password in .netrc or url embedded
Where .netrc files are using in the form:
machine <hostname> login <username> password <password>
And embedded urls would be in the form:
http://user:pass#hostname/repo
Since git won't do auth for you, you will need to configure a webserver such as apache to perform the auth, before passing the request onto the git tools. Also keep in mind that using the embedded method is a security risk, even if you use https since it is part of the url being requested.
If you want to be able to pull non-interactive, but prevent anonymous users from accessing the git repo, this should be a reasonably lightweight solution using apache for basic auth and preferably the .netrc file to store credentials. As a small gotcha, git will enable write access once authentication is being used, so either use anonymous http for read-only, or you'll need to perform some additional configuration if you want to prevent the non-interactive user from having write access.
See:
httpd.apache.org/docs/2.4/mod/mod_auth_basic.html for more on configuring basic auth
www.kernel.org/pub/software/scm/git/docs/git-http-backend.html for some examples on the apache config needed.
SSH
==============
Passphrase-Less
Opens up for security issues, since anyone who can get a hold of the ssh private key can now update the remote git repo as this user. If you want to use this non-interactively, I'd recommend installing something like gitolite to make it a little easier to ensure that those with the ssh private key can only pull from the repo, and it requires a different ssh key pair to update the repo.
See github.com/sitaramc/gitolite/ for more on gitolite.
stromberg.dnsalias.org/~strombrg/ssh-keys.html - for creating password less ssh keys:
May also want to cover managing multiple ssh keys: www.kelvinwong.ca/2011/03/30/multiple-ssh-private-keys-identityfile/
Passphase protected
Can use ssh-agent to unlock on a per-session basis, only really useful for interactive fetching from git. Since you mention root and only talk about performing 'git pull', it sounds like your use case is non-interactive. This is something that might be better combined with gitolite (github.com/sitaramc/gitolite/).
Summary
==============
Using something like gitolite will abstract a lot of the configuration away for SSH type set ups, and is definitely recommended if you think you might have additional repositories or need to specify different levels of access. It's logging and auditing are also very useful.
If you just want to be able to pull via http, the git-http-backend man page should contain enough information to configure apache to do the needful.
You can always combine anonymous http(s) for clone/pull, with passphrase protected ssh access required for full access, in which case there is no need to set up gitolite, you'll just add the ssh public key to the ~/.ssh/authorized_keys file.
See the answer to this question. You should use the SSH access instead of HTTPS/GIT and authenticate via your SSH public key. This should also work locally.
If you're using ssh access, you should have ssh agent running, add your key there and register your public ssh key on the repo end. Your ssh key would then be used automatically. This is the preferred way.
If you're using https access, you one would either
use a .netrc file that contains the credentials or
provide user/pass in the target url in the form https://user:pass#domain.tld/repo
With any of these three ways, it shouldn't ask for a password.

Sourcetree on Mac connecting to Gitolite asks for authentication

We've recently set up Gitolite server. All seems well. I can connect to it without a problem.
A new user has been set up, he's on a Mac and trying to use SourceTree. The only way I could get him to connect was for him to attempt to ssh to the server and I typed in the password (exited afterwards). Without that the system kept asking for a password for that server.
Is this normal behaviour?
How do non-sysadmin users gain access to gitolite?
Gitolite is based on forced command, which means non-interactive session.
So:
no password should ever be entered (assuming here non-password protected private key).
(as detailed in "how gitolite uses ssh").
no "non-sysadmin" should ever gain access to gitolite server itself.
So all he should need is a public key stored in ~/.ssh (making sure both his home and .ssh aren't group or world writable), registered in gitolite-admin/keys and published on the gitolite server .ssh/authorized_keys file.
From there, as mentioned in "Sourcetree and Gitolite":
If you are cloning a remote git repository, you need to tab out of the Source path/ URL field to activate the clone button.
The url will be validated at that point.
The url needs no special syntax working with gitolite, and even respects the host entries in your ssh conf file. So in my case a url of gitolite:workrepo is sufficient.

Send email when user changes password

I have a remote server to which I login using ssh. Is there a way to be notified through email (using a bash script) when someone changes the user password using passwd including the new password?
I am guessing it has to do with /etc/pam/passwd, but not entirely sure what the trigger and flags should be.
This would be useful if for example I give my access to a "friend" and they decide to lock me out of my account. Of course I could create a new account for them etc, but this is more of a "it should be possible" task rather than a practical one.
First, a Dope Slap
There's a rule that this question reminds me of... What is it? Oh yeah...
NEVER SHARE YOUR PASSWORDS WITH ANYONE!
Which also goes well with the rule.
NEVER SEND SOMETHING SECRET THROUGH EMAIL!
Sorry for the shouting. There's a rule in security that the likelihood a secret will get out is the square of the number of people who know it. My corollary is:
if ( people_who_know_secret > 1 ) {
It ain't a secret any more
}
In Unix, even the system administrator, the all powerful root, doesn't know your password.
Even worse, you want to email your password. Email is far from secure. It's normally just plain text sent over the Aether where anyone who's a wee bit curious can peek at it.
Method One: Allowing Users to use SSH without Knowing Your Password
Since you're using SSH, you should know that SSH has an alternate mechanism for verifying a user called Private/Public keys. It varies from system to system, but what you do is create a public/private key pair. You share your public key with the system you want to log into, but keep your private key private.
Once the remote machine has your public key, you can log into that system via ssh without knowing the password of that system.
The exact mechanism varies from machine to machine and it doesn't help that there are two different ssh protocols, so getting it to work will vary from system to system. On Linux and Macs, you generate your public/private key pair through the ssh-keygen command.
By default, ssh-keygen will produce a file called $HOME/.ssh/id_rsa.pub and $HOME/.ssh/id_rsa. The first one is your public key. You run ssh-keygen on both your machine and the machine you want to log into.
On the machine you're logging into, create a file called $HOME/.ssh/authorized_keys, and copy and paste your public key into this file. Have your friend also send you his public key, and paste that into the file too. Each public key will take up one line in the file.
If everything works, both you and your friend can use ssh to log into that remote machine without being asked for a password. This is very secure since your public key has to match your corresponding private key. If it doesn't you can't log in. That means even if other popel find your public key, they won't be able to log into that remote system.
Both you and your friend can log into that system without worrying about sharing a password.
Method Two: A Better Solution: Using SUDO
The other way to do this is to use sudo to allow your friend to act as you in certain respects. Sudo has a few advantages over actually sharing the account:
All use of SUDO is logged, so you have traceability. If something goes wrong, you know who to blame.
You can limit what people can do as SUDO. For example, your friend has to run a particular command as you, and nothing else. In this case, you can specify in the /etc/sudoers file that your friend can only run that one particular command. You can even specify if your friend can simply run the command, or require your friend to enter their password in order to run that command.
On Ubuntu Linux and on Macintoshes, the root password is locked, so you cannot log in as root. If you need to do something as root, you set yourself up as an administrator (I believe by putting yourself in the wheel group) and then using sudo to run required administrator functions.
The big disadvantage of Sudo is that it's more complex to setup and requires administrator access on the machine.
Try setting up public/private keys using SSH. It might take some tweaking to get it to work, but once it works, it's beautiful. Even better, you can run remote commands and use sep to copy files from one machine to the other -- all without the password prompt. This means that you can write shell scripts to do your work for you.
By the way, a sneaky trick is to set your remote shell to /bin/false. That way, you can't log into that system -- even using ssh, but you can run remote commands using ssh and use sep to copy files back and forth between systems.
Personal passwords are only supposed to be known by the user themselves. Not even the root user is supposed to know them, which is why they are stored encrypted. Of course, the root user has sufficient access to decrypt them, but the principle is the same.
If you are giving your "friend" access, them assign them proper privileges! Do not make them a root user, and you shouldn't be a root user either. Then you're "friend" won't have access to change your password, let along muck about in areas they aren't supposed to be in.
If you absolutely must monitor the passwd and shadow files, install iwatch. Then set it to watch the /etc/passwd and /etc/shadow files. If they change, it runs a script that decrypts the file and emails someone. If you keep a copy to diff against, you'll even know who changed. You should probably also gpg the email, so that it does not go over the internet in plain text, since it has everyone's password in it. Please note that any other users on the system will be upset by the dystopian world they find themselves in.
Just because root is the law of the land does not mean we want to be living in 1984.
Try some kind of:
alias passwd='passwd && echo 'Alert! Alert! Alert!' | mail -s 'pass change' alert#example.com'
Should be enough for you:)
Another possible solutions for those, who think, that alias is too mainstream)) :
1) You could make a cron job, that will be checking your /etc/shadow file every, for example, minute, and when the file changes, it will send you an alert-email. The easiest way here, I think, will be making md5 checksum
2) You can move /usr/bin/passwd to /usr/bin/passwd.sys and make a script with /usr/bin/passwd.sys && echo 'Alert! Alert! Alert!' | mail -s 'pass change' on it's place. And yes, this way is also could be discovered be the user and scrubed round:)

how to safely receive files from end-users via rsync

I'd like to allow users of my web application to upload the contents of a directory via rsync. These are just users who've signed up online, so I don't want to create permanent unix accounts for them, and I want to ensure that whatever files they upload are stored on my server only under a directory specific to their account. Ideally, the flow would be something like this:
user says "I'd like to update my files with rsync" via authenticated web UI
server says "OK, please run: rsync /path/to/yourfiles uploaduser123abc#myserver:/"
client runs that, updating whatever files have changed onto the server
upload location is chrooted or something -- we want to ensure client only writes to files under a designated directory on the server
ideally, client doesn't need to enter a password - the 123abc in the username is enough of a secret token to keep this one rsync transaction secure, and after the transaction this token is destroyed - no more rsyncs until a new step 1 occurs.
server has an updated set of user's files.
If you've used Google AppEngine, the desired behavior is similar to its "update" command -- it sends only the changed files to appengine for hosting.
What's the best approach for implementing something like this? Would it be to create one-off users and then run an rsync daemon in a chroot jail under those accounts? Are there any libraries (preferably Python) or scripts that might do something like this?
You can run ssh jailrooted and rsync normally, just use PAM to authenticate against an "alternate" authdb.

Resources