Local Git using Gogs

Hey there. I have been working on getting an installation of Gogs running. I want to get a git instance up that I control so that I can dig into how it works without that showing up on github. Controlling it also means that I can make as many private repositories as I want without worry. So, with all that said here was my adventure in getting this done.

Hyper-V Virtual Machine (Gen 2):

  • 1 vProcessor
  • 1024 MB RAM (Dynamic Memory)
  • 25 GB VHDX (on an SSD)
  • Ubuntu 18.04 Server

First Pass (Install + HTTPS)

I followed and spliced together a number of guides. My first attempts were to install Gogs from source, but I ran into issues with Go. Mostly that I could not for the life of me get it to recognize where Go was installed. Apparently I am not the only one who has had this problem. After a couple hours of trying to get that to work I moved on to installing Gogs from the binary.

Due to a confluence of r00k's Hack the Box walkthrough on Aragog, and several guides I was reading, I learned that git services are typically installed on a user named git and also that they typically do not have a shell or login privileges. So that's where I started on this.

After I installed Ubuntu and got to my sudo/root user notawful, I ran sudo apt-get update and sudo apt-get upgrade, followed by sudo apt-get autoremove. Once all that was done I added git as a user, then entered it to download and extract the Gogs binary.

sudo adduser --disabled-login -gecos 'Gogs' git
sudo su - git
wget https://dl.gogs.io/0.11.53/gogs_0.11.53_linux_amd64.tar.gz
tar -xzf gogs_0.11.53_linux_amd64.tar.gz

This created a new directory in git's home directory, /home/git/gogs, which contains all the files for Gogs to run. That is easy enough to do. From /home/git/gogs run ./gogs web. It runs correctly, and now I can finish configuration from the web interface. At this point my only worry is about an internet-based deployment since it is HTTP only at this point.

From a web browser on the Gogs installation screen I do the following:

  • Choose SQLLite3 since the binary includes this by default and there is no additional configuration required.
  • Add admin account gogsadmin with password r_3=zBd_aQH{. After enabling HTTPS I plan on adding a new admin user account and removing this one.

Now I exit/stop Gogs and exit back to notawful. Now I need to create some certificates. If I was running this in production I would create actual web certificates using Let's Encrypt, probably. Instead I will make a couple certificates using openssl. I use as the domain when making the certificate because I don't plan on setting up a DNS for my test environment.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/gogs-self.key -out /etc/ssl/private/gogs-self.crt
sudo chown git:git /etc/ssl/private/gogs-self.key
sudo chown git:git /etc/ssl/private/gogs-self.crt

I thought I knew what I was doing when I changed the owner of the key and certificate. My linux was rusty and when I made changes to the Gogs configuration file, it couldn't fetch them. I'll get to that in a second.

I made the following changes under the [server] heading in ~/gogs/custom/conf/app.ini from user git. There are a bunch of other entries in this section, but these are the only ones that I played with.

PROTOCOL = https
CERTFILE = /etc/ssl/private/gogs-self.crt
KEYFILE = /etc/ssl/private/gogs-self.key
LANDING_PAGE = explore

I imagine that some people already know what error I was about to run into. When I ran /home/git/gogs/gogs web it came back with an error that did not show on the on-screen output. I had to go to /home/git/gogs/log/gogs.log and check.
grepped output showing PERMISSION DENIED for /etc/ssl/private/gogs-self.crt

Yeah. So I know the files are owned by the right account, because I did that earlier. So I just needed to move them over to somewhere that git could actually see without sudo privileges. So I went back to user notawful.

sudo mv /etc/ssl/private/gogs-self.key /home/git/gogs-self.key
sudo mv /etc/ssl/private/gogs-self.crt /home/git/gogs-self.crt

Now, from git I reflect those changes in /home/git/gogs/custom/conf/app.ini and run /home/git/gogs/gogs web again.

CERTFILE = /etc/ssl/private/gogs-self.crt
KEYFILE = /etc/ssl/private/gogs-self.key

It works! Except I get an error that does not appear in gogs.log, but in the on-screen stuff. I did not read the whole error because I saw the magical phrase tls handshake and knew exactly what the error was. I confirmed in my browser that I was trying to navigate to, without specifying http:// or https://. Since I set the server to only operate with https, it was denying the request because it did not look the start of a TLS handshake. I instead navigated to and was greeted by...

Google Chrome screen stating certificate invalid, cannot proceed.

Okay, that's fair and something I should have expected by making my own certificate. I was able to click pas it and get into an HTTPS instance of Gogs. From there I created a new admin user and deleted the previous one that I created over HTTP. I haven't analyzed the traffic in the HTTP session but I don't trust it, so this is the mitigation I went with.

So, it works over HTTPS, and does not work over HTTP. If I had a DNS server I would have it redircet any HTTP requests to HTTPS to this instance. I will get to play around with git now that this is set up, but I still need to get this set up so I don't have to manually start the service every time.


Now, because I plan on running this in a DigitalOcean Droplet that will also contain an instance of by blog, I am a little worried about memory usage. Checking with Hyper-V I saw that the VM had 694MB assigned to the VM, but only 582MB was in use with Gogs running and being logged into the web service.

So then, how much was Gogs actually using? I stopped Gogs and exited git's shell. Logged only into notawful, the VM's memory usage was a 485MB, which means that Gogs was using about 97MB while running with one user. On a second test, I ran /home/git/gogs/gogs web & and then logged out of both git and notawful. Memory usage in this state was at about 563MB.

I have been told that Gogs memory footprint does not increase significantly with more users or more repositories. So, I think under reasonable circumstances I am likely to be able to run Ghost and Gogs on the same droplet with only 1GB of memory.

Second Pass (the same as the last, but with less fuck-ups)

As notawful:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get autoremove
sudo adduser --disabled-login git
sudo su - git

As git:

wget https://dl.gogs.io/0.11.53/gogs_0.11.53_linux_amd64.tar.gz
tar -xzf gogs_0.11.53_linux_amd64.tar.gz
cd gogs
./ gogs web

Connect to web site, select SQLLite3, create an admin user gogsadmin. Email doesn't matter, since Mailer service is disabled (and won't be enabled).

As notawful:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /home/git/gogs-self.key -out /home/git/gogs-self.crt
sudo chown git:git /home/git/gogs-self.key
sudo chown git:git /home/git/gogs-self.crt

As git, editing /home/git/gogs/custom/conf/app.ini:

PROTOCOL = https
CERTFILE = /home/git/gogs-self.crt
KEYFILE = /home/git/gogs-self.key
LANDING_PAGE = explore

As git from /home/git/gogs, run: ./gogs web &
From browser, log in to gogsadmin, create a new user and give them admin privileges. Then log into the new admin account and delete the gogsadmin.

Next Steps?

Figure out how to make this into an auto-run when the server starts. This is not something that I have done in a long time, and I have certainly never done so for a user that shouldn't be logging in. I will have to take some time to figure this side of things out.

Support the Author

Devon Taylor (They/Them) is a Canadian network architect, security consultant, and blogger. They have experience developing secure network and active directory implementations in low-budget and low-personnel environments. Their blog offers a unique and detailed perspective on security and game design, and they tweet about technology, security, games, and social issues. You can support their work via Patreon (USD), or directly via ko-fi.