Friday, November 12, 2010

Hosting Mercurial on a Synology NAS

Some time ago I ditched my subversion and wanted to try out a distributed sourcecontrolsystem. I had the choice between GIT and Mercurial: There is nothing to explain why I chose Mercurial, I just flipped a coin: but since then I'm quite happy with that decision.

Installing Mercurial on my Synology NAS was a peace of cake: you just needed to have access via SSH or Telnet, having the NAS bootstrapped and use the ipkg install command for installing it. It doesn't matter which version you actually take: I already used python-2.6 so I took the py26-mercurial.

After that Mercurial was already usable if you had direct access to the repositories, but since I'm not always in my LAN, I wanted also the possibility to have access via HTTPS or HTTP.

Mercurial has a build-in web server, which can serve the repository online: although its not recommended to use this permanently because it lacks of authentication methods and security, I gave this a try.

This webservice can be configured quite easily within the command, or you do it like me and use a config-file for that.

[collections]
#location of the repositories
#setting it this way lets the webserver parse all subdirectories for repositories
[rootlocationOfRepos] = [rootlocationOfRepos]


[web]
style = gitweb #you have more choices here, but gitweb looks the best ;)
allow_archive = bz2 gz zip
contact = Max A. Pfandl, max[at]pfandl.name
push_ssl = false

[ui]
username = madmap

For starting and stopping the hg serve I wrote a simple sh script which started me this service on port 666, using a PID-File for coordinating the process and configured by the config-file provided.

#!/bin/sh
#
# Startup script for mercurial server.
#
# Change following ines
APP_BIN=[LocationOfHG]


# Path to PID file of running mercurial process.
PID_FILE=[PIDFile]


state=$1

case "$state" in
'start')
echo "Mecurial Server service starting."
(${APP_BIN} serve --webdir-conf [locationof]/hgweb.config -p 666 -d  --pid-file ${PID_FILE})
;;

'stop')
if [ -f "${PID_FILE}" ]; then
PID=`cat "${PID_FILE}"`
if [ "${PID}" -gt 1 ]; then
kill -TERM ${PID}
echo "Stopping the Mercurial service PID=${PID}."
else
echo Bad PID for Mercurial -- \"${PID}\"
fi
else
echo No PID file recorded for mercurial
fi
;;
'restart')
if [ -f "${PID_FILE}" ]; then
PID=`cat "${PID_FILE}"`
if [ "${PID}" -gt 1 ]; then
kill -TERM ${PID}
echo "Stopping the Mercurial service PID=${PID}."
else
echo Bad PID for Mercurial -- \"${PID}\"
fi
else
echo No PID file recorded for mercurial
fi
echo "Mecurial Server service starting."
(${APP_BIN} serve --webdir-conf [locationof]/hgweb.config -p 666 -d  --pid-file ${PID_FILE})
;;
*)
echo "$0 {start|stop}"
exit 1
;;
esac

So now I had access from everywhere over port 666 and without any authentication whatsoever: This works fine, but of course I don't want everybody to have full access on my precious sourcecode!

So the first thing I did was close the port on my router: and now I was exactly where I was before: I had access within my LAN, but not from anywhere else. I needed to find a solution for authentication and security.

Therefore I used nginx. This is a lightweight webserver which can be nicely configured to work as a proxy-forwarder.

Installing of nginx was again made easy by using the ipkg install command and then you need to configure it.

My nginx.config lookes like this:

user  root root;
worker_processes  1;

error_log  /volume1/public/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        /volumeUSB3/usbshare/merc/nginx.pid;


events {
worker_connections  1024;
}


http {
include       mime.types;
default_type  application/octet-stream;

## Timeouts
client_body_timeout   600;
client_header_timeout 600;
send_timeout          600;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_cache off;
add_header    Cache-Control  no-cache;
## General Options
ignore_invalid_headers   on;
limit_zone gulag $binary_remote_addr 5m;
recursive_error_pages    on;
sendfile                 off;
server_name_in_redirect off;
server_tokens           off;

client_max_body_size 100m;
ssl_certificate [locationof]/hg.pfandl.name.pem;
ssl_certificate_key [locationof]/hg.pfandl.name.key;

gzip  on;

server {
listen 443;
ssl on;
server_name [publicURL];    # standard stuff
ssl_session_timeout 10m;

error_page 401 /401.html;
location = /{
auth_basic           "Required for Overview, if not provided you will get forwarded to the Public Area";
auth_basic_user_file [locationof]/htpasswd;
proxy_pass http://localhost:666; # or wherever hg serve is running
}

location = /robots.txt{
root [rootlocationofrobots];
}

location = /401.html{
#this 401.html only forwards to the public area
root [rootlocationof401];
}



location /{
#this only needs a password when you POST smth, for a GET request its allowed for anybody
limit_except GET{
auth_basic           "Restricted to push Changes";
auth_basic_user_file [locationof]/htpasswdPublic;
proxy_pass http://localhost:666; # or wherever hg serve is running
}
proxy_pass http://localhost:666; # or wherever hg serve is running
}
location ^~ /ATTIC/{
auth_basic           "Restricted Access to ATTIC Repo";
auth_basic_user_file[locationof]/htpasswd;
proxy_pass http://localhost:666; # or wherever hg serve is running
}

location ^~ /CAV/{
auth_basic           "Restricted Access to CAV Repo";
auth_basic_user_file [locationof]/htpasswd;
proxy_pass http://localhost:666; # or wherever hg serve is running
}

location ^~ /TECHTALK/{
auth_basic           "Restricted Access to TT Repo";
auth_basic_user_file [locationof]/htpasswd;
proxy_pass http://localhost:666; # or wherever hg serve is running
}
location ^~ /PRIVATE/{
auth_basic           "Restricted";
auth_basic_user_file [locationof]/htpasswd;
proxy_pass http://localhost:666; # or wherever hg serve is running
}

}
}

What you can see in this config is, that I created myself some selfsigned certificate and I use HTTPS so I have already some kind of encryption. Furthermore I can define in this config, who has which access to where: I can define readonly, full or no access per repository. The errorfile (401.html) you see is nothing but a forwarder to the public page on this server, so to the repository, everybody has read-access. The authentication is done via htpasswd-files which have the standard-format for linux. I used this Tool to create the files for me.


After doing all that stuff, everything was finally as expected: I had a running mercurial including full control over authentication (via nginx), encrypted file-transfers and public available over HTTPS.

17 comments:

  1. Very nice tutorial. I stopped before going to nginx but, up to then, every step was easily reproduceable.

    Thanks

    ReplyDelete
  2. The framework won't be online as you are expecting to utilize the old NAS as a DR server farm along these lines the old NAS will be turned off. click this link here now

    ReplyDelete
  3. The downsides of buying a NAS include cost and limitation. Buying a NAS is more expensive than assembling one. recover deleted data

    ReplyDelete
  4. This is on account of changing certain highlights on the server could influence different sites on that server. dedicated server hosting north america

    ReplyDelete
  5. What you get is really a worked in USB port you can plug memory sticks and outside capacity gadgets into. recover deleted data

    ReplyDelete
  6. It is important that all database exchanges can work autonomous of each other, while staying imperceptible to each other to encourage simultaneous exchanges inside a similar database.https://www.dbdesigner.net/

    ReplyDelete
  7. All in all, what makes data recovery so costly? Basically, data recovery is costly in light of the fact that it is a confounded procedure and very few organizations are had practical experience in this field.hard drive data recovery

    ReplyDelete
  8. Clients who approach the VPS can make changes to their site, store data on the hard drive, and even reboot their piece of the framework without having any impact on the other virtual servers that processing assets are being imparted to.
    affordable dedicated server hosting

    ReplyDelete
  9. Truth be told, endeavoring to run a hard drive that is physically harmed can exacerbate the issue. UK data recovery

    ReplyDelete
  10. Tragically these variables imply that, as a rule, recovery administrations are very costly.data recovery services

    ReplyDelete
  11. You have done a great job. I will definitely dig it and personally recommend to my friends. I am confident they will be benefited from this site. free domain registration and hosting south africa

    ReplyDelete
  12. The company was started to provide customer-friendly and cheap web hosting and reseller hosting to individuals and businesses.minecraft server hosting

    ReplyDelete
  13. Making a path for your this link non-master database developers to make great code that can keep running in a multi-processor condition will be an absolute necessity.

    ReplyDelete
  14. What's more, this assessment cost may not be incorporated into the real expense of data recovery.recover deleted data

    ReplyDelete
  15. It requires aptitudes and experience levels that are not ordinarily found in the normal PC fix man.recover deleted data

    ReplyDelete
  16. Bound together data is the idea of interconnecting an organization's telephone log with its site page examination to realize when that organization's clients are well on the way to get to both the site and contact client support. click here

    ReplyDelete