Skip to content

Using a local git mirror

Raphael Coeffic edited this page May 30, 2023 · 1 revision

Setup the local repository mirrors

  • obtain the list of submodule repository used (in the EdgeTx repository):
git submodule foreach --recursive --quiet git remote get-url origin
  • create directories for each github user

  • in each sub-directory, create a mirror repository:

git clone --mirror https://github.com/EdgeTX/edgetx.git

It should result in a tree like this:

$ tree -d -L 2 /data/git
/data/git
├── EdgeTX
│   ├── edgetx.git
│   ├── libopenui.git
│   └── lvgl.git
├── FreeRTOS
│   ├── FreeRTOS-Kernel.git
│   ├── FreeRTOS-Kernel-Community-Supported-Ports.git
│   └── FreeRTOS-Kernel-Partner-Supported-Ports.git
├── jbeder
│   └── yaml-cpp.git
├── lvgl
│   └── lvgl
├── nothings
│   └── stb.git
└── raphaelcoeffic
    └── AccessDenied.git

Create certificates

CA certificate

# CA config file
cat << EOF > ca.cnf
[req]
distinguished_name = req_distinguished_name
prompt = no
default_md = sha256

[req_distinguished_name]
C   = DE
ST  = Berlin
L   = Berlin
O   = EdgeTX
CN  = cloudbuild.local
EOF

# CA private key
openssl genrsa -out ca.key 2048

# Self-sign CA certificate (10 years valid)
openssl req -key ca.key -new -x509 -days 3650 -out ca.cert -config ca.cnf

Server certificate

  • OpenSSL configuration (github.cnf) to impersonate github.com:
# CA config file
cat << EOF > github.cnf
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
default_md = sha256

[req_distinguished_name]
C   = DE
ST  = Berlin
L   = Berlin
O   = EdgeTX
CN  = github.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = github.com
DNS.2 = www.github.com
EOF
  • Generate private key, CSR and sign it:
# Server private key
openssl genrsa -out server.key 2048

# Server Certificate Signing Request (CSR)
openssl req -new -key server.key -out server.csr -config github.cnf

# Sign this CSR (10 years valid)
openssl x509 -req -days 3650 -sha256 -in server.csr \
  -CA ca.cert -CAkey ca.key -CAcreateserial \
  -out server.cert \
  -extensions req_ext \
  -extfile github.cnf
  
# Create bundled certificate
cat server.cert ca.cert > bundled.cert

Use the certificates and serve Git/HTTPS

Checkout base container repository

# Checkout base container
git clone https://github.com/ynohat/git-http-backend

Apply diffs

diff --git a/Dockerfile b/Dockerfile
index 25e4d28..6798788 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -22,6 +22,7 @@ RUN apk add --update nginx && \
     rm -rf /var/cache/apk/*
 
 COPY nginx.conf /etc/nginx/nginx.conf
+COPY bundled.cert server.key /etc/nginx/certs/
 
 # launch fcgiwrap via spawn-fcgi; launch nginx in the foreground
 # so the container doesn't die on us; supposedly we should be
diff --git a/nginx.conf b/nginx.conf
index 38b3075..a2a3f19 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -10,7 +10,11 @@ events {
 
 http {
     server {
-        listen  *:80;
+        listen  *:443 ssl;
+        ssl_certificate     /etc/nginx/certs/bundled.cert;
+        ssl_certificate_key /etc/nginx/certs/server.key;
+        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
+        ssl_ciphers         HIGH:!aNULL:!MD5;
 
         root /www/empty/;
         index index.html;
@@ -23,7 +27,7 @@ http {
         #auth_basic            "Restricted";
         #auth_basic_user_file  /www/htpasswd;
 
-        location ~ /git(/.*) {
+        location / {
             # Set chunks to unlimited, as the bodies can be huge
             client_max_body_size            0;
 
@@ -31,7 +35,7 @@ http {
             include fastcgi_params;
             fastcgi_param GIT_HTTP_EXPORT_ALL "";
             fastcgi_param GIT_PROJECT_ROOT /git;
-            fastcgi_param PATH_INFO $1;
+            fastcgi_param PATH_INFO $uri;
 
             # Forward REMOTE_USER as we want to know when we are authenticated
             fastcgi_param   REMOTE_USER     $remote_user;

Start the Git HTTPS server

# Build container image
docker buildx build 

# Run container image
docker run -d -p 443:443 --name git-proxy -v /data/git:/git git-http-backend

Redirect workers to use the local mirror

Trust our mirror

  • mount bundled.cert into the workers' containers:
services:
  worker:
    volumes:
     - ./bundled.cert:/home/rootless/src/bundled.cert
  • set GIT_SSL_CAINFO=[path to bundled.cert] in the workers' environment (for example in api.env):
GIT_SSL_CAINFO=/home/rootless/src/bundled.cert
  • add github.com to the extra_hosts section in docker-compose.yml:
extra_hosts:
 - "github.com:[local IP to reach 'git-proxy' container]"