Installing private Git server on pfSense

UPDATE: Other possibility to all these steps it would be a public Git encrypted repository on an open platform, just if you don’t want to invest time on this option. As a comment if you have a Keybase.io account they have implemented this option for you using GitHub as Git platform.

Some times I have needed to share some private projects between different machines and I found quite useful to have an internal git server installed to be accessible from everywhere, once I solved, in a more or less secured way the access to my platform check this link if you’re interested in to know additional details about this process, I only need to install a minimal Git server.

The first choice I had to make was if I’m going to host the git server on my server or I could use other hardware, so I realized that my pfsense router could be the perfect place. Anyway it’s needed to check out how much free space we have:

 # df -h
 Filesystem                     Size    Used   Avail Capacity  Mounted on
 /dev/ufsid/569025cc62366d87     21G    872M     19G     4%    /

Now it’s time to install the git server package on our pfSense:

# pkg install git
 Updating pfSense-core repository catalogue...
 pfSense-core repository is up to date.
 Updating pfSense repository catalogue...
 pfSense repository is up to date.
 All repositories are up to date.
 The following 5 package(s) will be affected (of 0 checked):
 New packages to be INSTALLED:
 git: 2.14.1 [pfSense]
 p5-Authen-SASL: 2.16_1 [pfSense]
 p5-GSSAPI: 0.28_1 [pfSense]
 p5-Digest-HMAC: 1.03_1 [pfSense]
 p5-Error: 0.17025 [pfSense]
 Number of packages to be installed: 5
...
 ===> Creating groups.
 Creating group 'git_daemon' with gid '964'.
 ===> Creating users
 Creating user 'git_daemon' with uid '964'.
 Extracting git-2.14.1: 100%
 Message from git-2.14.1:
 ------------------------------------------------------------------------
 *************************** GITWEB *************************************
 If you installed the GITWEB option please follow these instructions:
 ...
 *************************** GITWEB *************************************
 *************************** CONTRIB ************************************
 If you installed the CONTRIB option please note that the scripts are
 installed in /usr/local/share/git-core/contrib. Some of them require
 other ports to be installed (perl, python, etc), which you may need to
 install manually.
 *************************** CONTRIB ************************************
 ------------------------------------------------------------------------

I’m not going to use a web interface so I’m not going into any detail about how to install gitweb package. Let’s create the service user:

# adduser
 Username: git
 Full name: git
 Uid (Leave empty for default):
 Login group [git]:
 Login group is git. Invite git into other groups? []:
 Login class [default]:
 Shell (sh csh tcsh ssh_tunnel_shell scponly scponlyc git-shell nologin) [sh]:
 Home directory [/home/git]:
 Home directory permissions (Leave empty for default):
 Use password-based authentication? [yes]:
 Use an empty password? (yes/no) [no]:
 Use a random password? (yes/no) [no]:
 Enter password:
 Enter password again:
 Lock out the account after creation? [no]: ç
 Lock out the account after creation? [no]:
 Username   : git
 Password   : *****
 Full Name  : git
 Uid        : 1005
 Class      :
 Groups     : git
 Home       : /home/git
 Home Mode  :
 Shell      : /bin/sh
 Locked     : no
 OK? (yes/no): yes
 adduser: INFO: Successfully added (git) to the user database.
 Add another user? (yes/no): no
 Goodbye!

With this user created we can enable SSH access to users who are going to use this service, so we just need put their public SSH keys into authorized_keys file in git user account. This can be done with ssh-copy-id command or just copying public keys manually.

For a proper installation is needed to setup the right permissions:

 $ mkdir .ssh && chmod 700 /home/git/.ssh/
 $ cd .ssh && ls -ld .
 drwx------  2 git  git  512 Feb  8 14:28 .
 $ touch authorized_keys && chmod 600 authorized_keys

Let’s create a directory structure to store our ultra-secret projects, this part is very personal so I’m going a be a little generic here (logged as git user, by the way):

$ mkdir -p WHEREVER_YOU_WANT_PATH/secret.git && cd WHEREVER_YOU_WANT_PATH/secret.git
 $ git init --bare
 Initialized empty Git repository in WHEREVER_YOU_WANT_PATH/secret.git/
 $ ls -l
 total 32
 -rw-r--r--  1 git  git   23 Feb 10 10:17 HEAD
 drwxr-xr-x  2 git  git  512 Feb 10 10:17 branches
 -rw-r--r--  1 git  git   66 Feb 10 10:17 config
 -rw-r--r--  1 git  git   73 Feb 10 10:17 description
 drwxr-xr-x  2 git  git  512 Feb 10 10:17 hooks
 drwxr-xr-x  2 git  git  512 Feb 10 10:17 info
 drwxr-xr-x  4 git  git  512 Feb 10 10:17 objects
 drwxr-xr-x  4 git  git  512 Feb 10 10:17 refs

Client side configuration

Now it’s time of the funny part because we are going to config the client side:

client_host:$ vim ~/.ssh/config
 # PRIVATE HOME GIT SERVER SETTINGS
 Host gitserver
     Hostname YOUR_PUBLIC / YOUR_DNS_NAME
     User git
     Port CUSTOM_PORT (WHERE YOUR SSH SERVER IS LISTENING)
 client_host:$ mkdir my_secret_project && cd my_secret_project
 client_host:$ git init
 Initialized empty Git repository in WHEREVER/my_secret_project/.git/
 client_host:$ git add .
 client_host:$ git commit -m 'initial commit'
 On branch master
 Initial commit
 nothing to commit
 client_host:$ git remote add origin gitserver:WHEREVER_YOU_WANT_PATH/secret.git
 client_host:$ git push origin master
 Counting objects: 3, done.
 Writing objects: 100% (3/3), 227 bytes | 227.00 KiB/s, done.
 Total 3 (delta 0), reused 0 (delta 0)
 To ssh://gitserver:WHEREVER_YOU_WANT_PATH/secret.git
  * [new branch]      master -> master

Note that I made some tests while I was writing this entry because of that the push command has written 3 objects in my case.

When other user want to clone this repository “just” need to execute:

 $ GIT_SSH_COMMAND='ssh -p CUSTOM_SSH_PORT' git clone ssh://git@YOUR_IP:WHEREVER_YOU_WANT_PATH/secret.git
 Cloning into 'secret'...
 remote: Counting objects: 3, done.
 remote: Total 3 (delta 0), reused 0 (delta 0)
 Receiving objects: 100% (3/3), done.

I highly important recommendation is to use git-shell option in our configuration just to get a more secure environment.

# chsh -s /usr/local/bin/git-shell git
 chsh: user information updated
 # grep git: /etc/passwd
 git:*:1005:1005:git:/home/git:/usr/local/bin/git-shell

Installation reference link:

Have fun!

“Nothing shows a man’s character more than what he laughs at”
— J. W. von Goethe

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s