1

I have an Apache server that will host several sites and a private web interface that aims to automate the deployment of a site from a git SSH URL. Those git repos are on the same machine, hold by a local Gitlab instance and owned by root, so SSH is needed (or I'm missing something).

So we have PHP running shell commands as www-data to clone publicly accessible websites from a root protected repo on the same machine.

Virtualhosts are managed with mod_vhost_alias if that matters. I also do know about cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys.

But generating ssh keys for www-data doesn't seem like a great idea.

If I create a dedicated "web" user to that matter and generate ssh keys for it, then www-data can't clone in that directory. I can use ACL on the folder but it still doesn't get its ssh access.

Or maybe should I su web with PHP at first ? In this case files wouldn't be owned by www-data which can cause sites not to work.

This reaches the point where I lose track of what's good and what's secure. I can find a working solution eventually but it won't be clean and probably won't be secure.

Additional info :

  • This is not a production server. All the sites (around 10 at once) will get a very limited traffic and most of them will be password protected anyway (I said "publicly accessible" above to cover the most extreme cases).

  • Development is made in a local environment, changes are pushed to the online version with git hooks.

  • There is only one web interface that can launch the deployment process. Only a few trusted users have access to it.

  • Deployment won't change Apache configuration as mod_vhost_alias will handle vhosts and nothing else is needed.

  • All the sites will have a public folder, the rest of the files won't be accessible. Deployment script are already written at the time of deployment and can easily be used for this purpose.

  • Mid-deployment issues don't need to be addressed.

kursus
  • 133
  • 1
  • 5
  • You're right I have this in mind, overall I really want it to make as clean and simple as possible so I'm probably gonna drop the "one click install" and just create an install script that I will drop on the server so the web user can execute it though SSH. Thank for all your advice ! – kursus Jan 08 '17 at 13:25

1 Answers1

1

Do not mix development and production. Ideally, the production server does NOT contain VCS - or any other traces of development toolchain. Since you are now putting effort into automation of deployment, increase the seperation while you are at it.

Apart from that: Seperate permissions for seperate tasks. An admin interface requests deployment. A web server serves mostly-immutable files. A deployment script writes files.

  1. The user serving the files should not be able to write to (almost any of) its files.
  2. The user deploying the sites for the apache should setup such permissions and avoid mid-deployment serving of files (a developer may not have thought of side-effects of apache accessing anything while the applications is not fully copies)
  3. The user deploying the files should have readonly permissions for the git and only deploy committed and tagged versions (and checkout in a similar fashion as developers already do)
  4. a php web interface should never deal with any satanic shell magic. tag a site as "needs deployment" by any means (creating a folder etc) and be done with it (do NOT deploy snychronously in a web interface)
  5. the deployment script should be agnostic of the application it is deploying beyond some common standards ("the files for apache are in folder X", "the tmp folder should be places under the name Y")

How I have done it in an apparently similar setup: A script, owned and cron-executed by the user deploy (part of group www-data). The user deploy has the ssh key for a readonly account to the git server (in your case, managed via gitlab). The script picks up the repository names that were marked and deploys like this:

  1. check if last deployment was clean
  2. check if any sites needs to be deployed
  3. tear down (stop webserver from serving half-copied sites)
  4. if necessary get a clone (in your case, a readonly user on the git)
  5. checkout new version (for sanity: the latest tagged one that matches some reasonable regex)
  6. setup (copy files to webroot, in your current, unadvisable case, thats a local folder, chown to www-data)
  7. remove mark "needs to be deployed" for this site
  8. mark deployment as successful
anx
  • 8,963
  • 5
  • 24
  • 48
  • 1
    Thank you for your answer. I've edited the question with as much info as possible, it should cover your comment and the first part of your answer. As for the second part : point #6 wouldn't it be better to use ACL ? – kursus Jan 07 '17 at 09:14
  • the post-copy chowning mitigates a number of strange race conditions during deployment. this is harder to get right with ACL. rule: consider ACLs an extension which has to carry its weight in added complexity - or should be avoided. – anx Jan 08 '17 at 02:01