Filed Under (Mercurial, Nginx) by Marcin Kuźmiński on November-15-2009

Today is a great day ;) i switched my repos from svn to mercurial.
I was still thinking about GIT but there where three key points that made me choose mercurial

Cons: it’s slower than GIT ( but who cares :D )

So after installing mercurial and moving my svn repos with history with hgsvn ( which can also do push to svn )
I started to setup easy access to the repository using nginx. I’ll show you how to setup an SSL http based repository to do PUSH/PULL/CLONE what ever.

Firstly we have to make self signed ssl certificates.
I found on of the easiest tutorials available you can find it here: http://www.akadia.com/services/ssh_test_certificate.html

OK when we have the ssl certificates for our server. Put it somewhere on the server so nginx can access it.
We have to setup a new virtual host for nginx that will only do ssl connections
and have basic auth additionally.

Here’s the example config:

server {
    listen          443;
    server_name     hg.yourserver.com;
    ssl    on;
    ssl_certificate    /home/ssl_certs/hg_cert.crt;
    ssl_certificate_key     /home/ssl_certs/hg_cert.key;
    access_log      /var/log/nginx/hg.log;
    auth_basic      "mercurial server";
    auth_basic_user_file    /etc/nginx/.htpasswd;

    location / {
        proxy_pass      http://127.0.0.1:8001;
        #here's where the hg server runs
        include         /etc/nginx/proxy.conf;
    }
}

Few thing to notice.
.htpasswd file has to be in a format <username>:<cryptPassword> if you don’t have apache
installed you can use my password generator for generating crypt password. This username
and password will be used to do pull/push from console and eclipse.
Another important thing is that when you run hg serve you must specify the -a 127.0.0.1 option which is
for the address the mercurial server runs. Hg serve default is to start at all interfaces
so you have this port open outside and your ssl/passwd protection is for nothing…

I run my using hg serve –webdir-conf=/etc/hg/hgweb.conf -d -p 8001 -a 127.0.0.1

The hgweb.conf should be with

push_ssl = false
#since nginx is doing the SSL
allow_push = * #NGINX  is doing the auth
style = gitweb

O and one more thing remember that your repo should be accessible to hg serv.
I made a mistake and run hg serve as www-data and my repo was to my home user,
and i had internal server error when trying to do push to server.

So now you can have your repo via http with SSL and nginx authentication.



Filed Under (Nginx, Python) by Marcin Kuźmiński on June-23-2009

Recently i made a simple random password generator with ability to make n-length passwords with appropriate hash of this password. Especially i was interested in CRYPT to create a password for nginx passwd files. You need to make a password hashed with crypt in order to put it to any *NIX passwd file. Which has a format of username:password using the to_crypt function you can create password for these type of access files. You can use any salt for the passwords.

Heres the code fell free to use it:

'''
@author: marcink
This is a simple class for generating password from
different sets of characters

functions sha1,md5 and crypt returns a tuple of (generated_password,hashed_password,type)

'''

from hashlib import sha1, md5
import random
import crypt

class PasswordGenerator(object):

    def __init__(self, passwd = ''):

        self.ALPHABETS_NUM = r'''1234567890'''#[0]
        self.ALPHABETS_SMALL = r'''qwertyuiopasdfghjklzxcvbnm'''#[1]
        self.ALPHABETS_BIG = r'''QWERTYUIOPASDFGHJKLZXCVBNM'''#[2]
        self.ALPHABETS_SPECIAL = r'''`-=[]\;',./~!@#$%^&*()_+{}|:"<>?'''    #[3]
        self.ALPHABETS_FULL = self.ALPHABETS_BIG + self.ALPHABETS_SMALL + self.ALPHABETS_NUM + self.ALPHABETS_SPECIAL#[4]
        self.ALPHABETS_ALPHANUM = self.ALPHABETS_BIG + self.ALPHABETS_SMALL + self.ALPHABETS_NUM#[5]
        self.ALPHABETS_BIG_SMALL = self.ALPHABETS_BIG + self.ALPHABETS_SMALL
        self.ALPHABETS_ALPHANUM_BIG = self.ALPHABETS_BIG + self.ALPHABETS_NUM#[6]
        self.ALPHABETS_ALPHANUM_SMALL = self.ALPHABETS_SMALL + self.ALPHABETS_NUM#[7]
        self.passwd = passwd

    def gen_password(self, len, type):
        #''.join(seq) is 30x faster that str_password+=random.choice(type)
        self.passwd = ''.join([random.choice(type) for _ in xrange(len) ])
        return self

    def to_md5(self):
        return (self.passwd, md5(self.passwd).hexdigest(),'md5')

    def to_sha1(self):
        return (self.passwd, sha1(self.passwd).hexdigest(),'sha1')

    def to_crypt(self, salt):
        return (self.passwd, crypt.crypt(self.passwd, salt),'crypt[salt=%s]' % salt)

    def to_plain(self):
        return self.passwd

if __name__ == "__main__":
    passwd_gen = PasswordGenerator()

    #print 8-letter password containing only big and small letters of alphabet
    print passwd_gen.gen_password(8, passwd_gen.ALPHABETS_BIG_SMALL).to_plain()

    #print 8 letter password containing numbers only and return crypt hash of it
    print passwd_gen.gen_password(8, passwd_gen.ALPHABETS_NUM).to_crypt(salt = 'ab')

    # create an instance of passwordGenerator with you own password
    my_custom_password = PasswordGenerator('my_secret_password')
    print my_custom_password.to_plain()

    #print md5 of that password
    print my_custom_password.to_md5()

    '''
    sample output:
    raeBvpdd
    ('10047981', 'abOaHGCbrkA7U', 'crypt[salt=ab]')
    my_secret_password
    ('my_secret_password', '7ee416d527a2d047751c026d82dbbeef', 'md5')
    '''