diff options
Diffstat (limited to 'roles/git')
-rw-r--r-- | roles/git/files/etc/cgitrc | 2 | ||||
-rw-r--r-- | roles/git/files/etc/nginx/sites-available/git | 100 | ||||
-rw-r--r-- | roles/git/files/etc/systemd/system/cgit.service | 23 | ||||
-rw-r--r-- | roles/git/files/etc/systemd/system/cgit.socket | 11 | ||||
-rw-r--r-- | roles/git/files/etc/systemd/system/git-http-backend.service | 21 | ||||
-rw-r--r-- | roles/git/files/etc/systemd/system/git-http-backend.socket | 11 | ||||
-rw-r--r-- | roles/git/files/etc/uwsgi/apps-available/cgit.ini | 6 | ||||
-rw-r--r-- | roles/git/files/etc/uwsgi/apps-available/git-http-backend.ini | 4 | ||||
-rw-r--r-- | roles/git/handlers/main.yml | 13 | ||||
-rw-r--r-- | roles/git/tasks/cgit.yml | 137 | ||||
-rw-r--r-- | roles/git/tasks/gitolite.yml | 10 | ||||
-rw-r--r-- | roles/git/tasks/main.yml | 6 | ||||
l--------- | roles/git/templates/etc/nginx/snippets/git.fripost.org.hpkp-hdr.j2 | 1 |
13 files changed, 216 insertions, 129 deletions
diff --git a/roles/git/files/etc/cgitrc b/roles/git/files/etc/cgitrc index b862dc3..a7e33cd 100644 --- a/roles/git/files/etc/cgitrc +++ b/roles/git/files/etc/cgitrc @@ -1,29 +1,29 @@ # # cgit config # see cgitrc(5) for details # Enable caching of up to 1000 output entries cache-size=1000 # Specify some default clone url prefixes -clone-url=https://$HTTP_HOST/$CGIT_REPO_NAME ssh://$HTTP_HOST/$CGIT_REPO_NAME +clone-url=https://$HTTP_HOST/$CGIT_REPO_NAME ssh://gitolite@$HTTP_HOST/$CGIT_REPO_NAME # Specify the css, logo and favicon urls css=/static/cgit.css logo=/static/cgit.png favicon=/static/favicon.ico # Show owner on index page enable-index-owner=1 # Disallow dumb http transport git clone enable-http-clone=0 # Show extra links for each repository on the index page enable-index-links=1 # Enable ASCII art commit history graph on the log pages enable-commit-graph=1 # Show number of affected files per commit on the log pages enable-log-filecount=1 diff --git a/roles/git/files/etc/nginx/sites-available/git b/roles/git/files/etc/nginx/sites-available/git index 75c1512..9e9d16e 100644 --- a/roles/git/files/etc/nginx/sites-available/git +++ b/roles/git/files/etc/nginx/sites-available/git @@ -1,92 +1,78 @@ server { listen 80; listen [::]:80; server_name git.fripost.org; + include /etc/lacme/nginx.conf; + access_log /var/log/nginx/git.access.log; error_log /var/log/nginx/git.error.log info; - location ^~ /static/ { - alias /usr/share/cgit/; - expires 30d; - } - - # Bypass the CGI to return static files stored on disk. Try first repo with - # a trailing '.git', then without. - location ~* "^/((?U)[^/]+)(?:\.git)?/objects/(?:[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(?:pack|idx))$" { - root /var/lib/gitolite/repositories; - try_files /$1.git/objects/$2 /$1/objects/$2 =404; - expires 30d; - # TODO honor git-daemon-export-ok - } - - # disallow push over HTTP/HTTPS - location ~* "^/[^/]+/git-receive-pack$" { return 403; } - - location ~* "^/[^/]+/(?:HEAD|info/refs|objects/info/[^/]+|git-upload-pack)$" { - gzip off; - include uwsgi_params; - uwsgi_modifier1 9; - uwsgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; - uwsgi_pass unix:/run/uwsgi/app/git-http-backend/socket; - } - - - # send all other URLs to cgit location / { - gzip off; - include uwsgi_params; - uwsgi_modifier1 9; - uwsgi_pass unix:/run/uwsgi/app/cgit/socket; + return 301 https://$host$request_uri; } } server { - listen 443; - listen [::]:443; + listen 443 ssl http2; + listen [::]:443 ssl http2; server_name git.fripost.org; - include ssl/config; - ssl_certificate /etc/nginx/ssl/git.fripost.org.pem; - ssl_certificate_key /etc/nginx/ssl/git.fripost.org.key; - access_log /var/log/nginx/git.access.log; error_log /var/log/nginx/git.error.log info; - location ^~ /static/ { - alias /usr/share/cgit/; - expires 30d; - } + include snippets/headers.conf; + add_header Content-Security-Policy + "default-src 'none'; img-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'; frame-ancestors 'none'; form-action 'self'"; - # Bypass the CGI to return static files stored on disk. Try first repo with - # a trailing '.git', then without. - location ~* "^/((?U)[^/]+)(?:\.git)?/objects/(?:[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(?:pack|idx))$" { - root /var/lib/gitolite/repositories; - try_files /$1.git/objects/$2 /$1/objects/$2 =404; + include snippets/ssl.conf; + ssl_certificate ssl/git.fripost.org.pem; + ssl_certificate_key ssl/git.fripost.org.key; + include snippets/git.fripost.org.hpkp-hdr; + + gzip on; + gzip_vary on; + gzip_min_length 256; + gzip_types application/javascript application/json application/xml image/svg+xml image/x-icon text/css text/plain; + + location ^~ /static/ { expires 30d; - # TODO honor git-daemon-export-ok + alias /usr/share/cgit/; } # disallow push over HTTP/HTTPS - location ~* "^/[^/]+/git-receive-pack$" { return 403; } + location ~ "^/.+/git-receive-pack$" { return 403; } - location ~* "^/[^/]+/(?:HEAD|info/refs|objects/info/[^/]+|git-upload-pack)$" { + location ~ "^/.+/(?:info/refs|git-upload-pack)$" { + limit_except GET POST { deny all; } + fastcgi_buffering off; gzip off; - include uwsgi_params; - uwsgi_modifier1 9; - uwsgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; - uwsgi_pass unix:/run/uwsgi/app/git-http-backend/socket; + + fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; + fastcgi_param NO_BUFFERING ""; + + # cf. git-http-backend(1) + fastcgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; + fastcgi_param PATH_INFO $uri; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_pass unix:/run/git-http-backend.socket; } + location = /robots.txt { root /usr/share/cgit; } + location = /favicon.ico { root /usr/share/cgit; } # send all other URLs to cgit location / { - gzip off; - include uwsgi_params; - uwsgi_modifier1 9; - uwsgi_pass unix:/run/uwsgi/app/cgit/socket; + fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_pass unix:/run/cgit.socket; } } diff --git a/roles/git/files/etc/systemd/system/cgit.service b/roles/git/files/etc/systemd/system/cgit.service new file mode 100644 index 0000000..08037ac --- /dev/null +++ b/roles/git/files/etc/systemd/system/cgit.service @@ -0,0 +1,23 @@ +[Unit] +Description=hyperfast web frontend for git repositories written in C +Documentation=https://git.zx2c4.com/cgit/ + +[Service] +User=_cgit +Group=nogroup +SupplementaryGroups=gitolite +ExecStart=/usr/sbin/fcgiwrap +SyslogIdentifier=cgit +# +# Hardening +NoNewPrivileges=yes +PrivateDevices=yes +ProtectHome=yes +ProtectSystem=strict +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ReadWriteDirectories=/var/cache/cgit + +[Install] +WantedBy=multi-user.target diff --git a/roles/git/files/etc/systemd/system/cgit.socket b/roles/git/files/etc/systemd/system/cgit.socket new file mode 100644 index 0000000..bba4bef --- /dev/null +++ b/roles/git/files/etc/systemd/system/cgit.socket @@ -0,0 +1,11 @@ +[Unit] +Description=hyperfast web frontend for git repositories written in C +Documentation=https://git.zx2c4.com/cgit/ + +[Socket] +ListenStream=%t/cgit.socket +SocketUser=www-data +SocketMode=0600 + +[Install] +WantedBy=sockets.target diff --git a/roles/git/files/etc/systemd/system/git-http-backend.service b/roles/git/files/etc/systemd/system/git-http-backend.service new file mode 100644 index 0000000..f973370 --- /dev/null +++ b/roles/git/files/etc/systemd/system/git-http-backend.service @@ -0,0 +1,21 @@ +[Unit] +Description=Git HTTP backend +Documentation=man:git-http-backend(1) + +[Service] +DynamicUser=yes +SupplementaryGroups=gitolite +ExecStart=/usr/sbin/fcgiwrap +SyslogIdentifier=git-http-backend +# +# Hardening +NoNewPrivileges=yes +PrivateDevices=yes +ProtectHome=yes +ProtectSystem=strict +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes + +[Install] +WantedBy=multi-user.target diff --git a/roles/git/files/etc/systemd/system/git-http-backend.socket b/roles/git/files/etc/systemd/system/git-http-backend.socket new file mode 100644 index 0000000..c2820d4 --- /dev/null +++ b/roles/git/files/etc/systemd/system/git-http-backend.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Git HTTP backend +Documentation=man:git-http-backend(1) + +[Socket] +ListenStream=%t/git-http-backend.socket +SocketUser=www-data +SocketMode=0600 + +[Install] +WantedBy=sockets.target diff --git a/roles/git/files/etc/uwsgi/apps-available/cgit.ini b/roles/git/files/etc/uwsgi/apps-available/cgit.ini deleted file mode 100644 index 2fb5b25..0000000 --- a/roles/git/files/etc/uwsgi/apps-available/cgit.ini +++ /dev/null @@ -1,6 +0,0 @@ -[uwsgi] -plugins = cgi -procname-master = uwsgi %(deb-confname) -cgi = /usr/lib/cgit/cgit.cgi -uid = cgit -gid = www-data diff --git a/roles/git/files/etc/uwsgi/apps-available/git-http-backend.ini b/roles/git/files/etc/uwsgi/apps-available/git-http-backend.ini deleted file mode 100644 index 6718237..0000000 --- a/roles/git/files/etc/uwsgi/apps-available/git-http-backend.ini +++ /dev/null @@ -1,4 +0,0 @@ -[uwsgi] -plugins = cgi -procname-master = uwsgi %(deb-confname) -cgi = /usr/lib/git-core/git-http-backend diff --git a/roles/git/handlers/main.yml b/roles/git/handlers/main.yml index d52c9cc..6212d91 100644 --- a/roles/git/handlers/main.yml +++ b/roles/git/handlers/main.yml @@ -1,9 +1,18 @@ --- - name: systemctl daemon-reload command: /bin/systemctl daemon-reload -- name: Restart uWSGI - service: name=uwsgi state=restarted +- name: Stop cgit + service: name=cgit.service state=stopped + +- name: Restart cgit + service: name=cgit.socket state=restarted + +- name: Stop git-http-backend + service: name=git-http-backend.service state=stopped + +- name: Restart git-http-backend + service: name=git-http-backend.socket state=restarted - name: Restart Nginx service: name=nginx state=restarted diff --git a/roles/git/tasks/cgit.yml b/roles/git/tasks/cgit.yml index a8be1fc..120f204 100644 --- a/roles/git/tasks/cgit.yml +++ b/roles/git/tasks/cgit.yml @@ -1,111 +1,144 @@ - name: Install cgit - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - cgit - highlight - - uwsgi + - fcgiwrap + +- name: Stop and disable fcgiwrap socket + service: name=fcgiwrap.socket state=stopped enabled=false + +- name: Stop fcgiwrap service + service: name=fcgiwrap.service state=stopped - name: Configure cgit copy: src=etc/cgitrc dest=/etc/cgitrc owner=root group=root mode=0644 - register: r1 notify: - - Restart uWSGI + - Stop cgit - name: Copy /usr/lib/cgit/filters/syntax-highlighting2.sh copy: src=usr/lib/cgit/filters/syntax-highlighting2.sh dest=/usr/lib/cgit/filters/syntax-highlighting2.sh owner=root group=root mode=0755 - register: r2 notify: - - Restart uWSGI + - Stop cgit -- name: Create a user 'cgit' - user: name=cgit system=yes - home=/var/www +- name: Create '_cgit' user + user: name=_cgit system=yes + group=nogroup + home=/nonexistent shell=/usr/sbin/nologin password=! state=present - register: r3 notify: - - Restart uWSGI + - Stop cgit -- name: Create /etc/uwsgi/apps-available/{cgit,git-http-backend}.ini - copy: src=etc/uwsgi/apps-available/{{ item }}.ini - dest=/etc/uwsgi/apps-available/{{ item }}.ini +# Make it sticky: `dpkg-statoverride --add _cgit nogroup 0700 /var/cache/cgit` +- name: Create cache directory /var/cache/cgit + file: path=/var/cache/cgit + state=directory + owner=_cgit group=nogroup + mode=0700 + +- name: Copy cgit service unit + copy: src=etc/systemd/system/cgit.service + dest=/etc/systemd/system/cgit.service owner=root group=root mode=0644 - register: r4 - with_items: - - cgit - - git-http-backend notify: - - Restart uWSGI + - systemctl daemon-reload + - Stop cgit -- name: Create /etc/uwsgi/apps-enabled/{cgit,git-http-backend}.ini - file: src=../apps-available/{{ item }}.ini - dest=/etc/uwsgi/apps-enabled/{{ item }}.ini +- name: Copy cgit socket unit + copy: src=etc/systemd/system/cgit.socket + dest=/etc/systemd/system/cgit.socket owner=root group=root - state=link force=yes - register: r5 - with_items: - - cgit - - git-http-backend + mode=0644 notify: - - Restart uWSGI + - systemctl daemon-reload + - Restart cgit -- name: Start uWSGI - service: name=nginx state=started - when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed) +- name: Disable cgit service + service: name=cgit.service enabled=false + +- name: Start cgit socket + service: name=cgit.socket state=started enabled=true - meta: flush_handlers -- name: Add 'cgit' & 'www-data' to the group 'gitolite' - user: name={{ item }} groups=gitolite append=yes - with_items: - # for the cgit interface - - cgit - # for pulls over HTTP/HTTPS - - www-data +- name: Copy git-http-backend service unit + copy: src=etc/systemd/system/git-http-backend.service + dest=/etc/systemd/system/git-http-backend.service + owner=root group=root + mode=0644 + notify: + - systemctl daemon-reload + - Stop git-http-backend -- name: Generate a private key and a X.509 certificate for Nginx - command: genkeypair.sh x509 - --pubkey=/etc/nginx/ssl/git.fripost.org.pem - --privkey=/etc/nginx/ssl/git.fripost.org.key - --ou=WWW --cn=git.fripost.org --dns=git.fripost.org - -t rsa -b 4096 -h sha512 - register: r1 - changed_when: r1.rc == 0 - failed_when: r1.rc > 1 +- name: Copy git-http-backend socket unit + copy: src=etc/systemd/system/git-http-backend.socket + dest=/etc/systemd/system/git-http-backend.socket + owner=root group=root + mode=0644 notify: - - Restart Nginx - tags: - - genkey + - systemctl daemon-reload + - Restart git-http-backend + +- name: Disable git-http-backend service + service: name=git-http-backend.service enabled=false + +- name: Start git-http-backend socket + service: name=git-http-backend.socket state=started enabled=true + +- meta: flush_handlers + - name: Copy /etc/nginx/sites-available/git copy: src=etc/nginx/sites-available/git dest=/etc/nginx/sites-available/git owner=root group=root mode=0644 - register: r2 + register: r1 notify: - Restart Nginx - name: Create /etc/nginx/sites-enabled/git file: src=../sites-available/git dest=/etc/nginx/sites-enabled/git owner=root group=root state=link force=yes + register: r2 + notify: + - Restart Nginx + +- name: Copy HPKP header snippet + # never modify the pined pubkeys as we don't want to lock out our users + template: src=etc/nginx/snippets/git.fripost.org.hpkp-hdr.j2 + dest=/etc/nginx/snippets/git.fripost.org.hpkp-hdr + validate=/bin/false + owner=root group=root + mode=0644 register: r3 notify: - Restart Nginx - name: Start Nginx service: name=nginx state=started when: not (r1.changed or r2.changed or r3.changed) - meta: flush_handlers + +- name: Fetch Nginx's X.509 certificate + # Ensure we don't fetch private data + become: False + fetch_cmd: cmd="openssl x509 -noout -pubkey" + stdin=/etc/nginx/ssl/git.fripost.org.pem + dest=certs/public/git.fripost.org.pub + tags: + - genkey diff --git a/roles/git/tasks/gitolite.yml b/roles/git/tasks/gitolite.yml index 5cbce23..e7d1fe3 100644 --- a/roles/git/tasks/gitolite.yml +++ b/roles/git/tasks/gitolite.yml @@ -9,28 +9,28 @@ password=* state=present - name: Create directory ~gitolite/.ssh file: path=/var/lib/gitolite/.ssh state=directory owner=gitolite group=gitolite mode=0700 - name: Create /var/lib/gitolite/projects.list file: path=/var/lib/gitolite/projects.list owner=gitolite group=gitolite mode=0644 # See /usr/share/doc/gitolite3/README.txt.gz for gitolite initiation or # migration. # sudo -u gitolite gitolite setup -pk /path/to/id_rsa - name: Configure gitolite lineinfile: dest=/var/lib/gitolite/.gitolite.rc - "regexp=^(\\s*{{ item.var }}\\s*=>\\s*)" - "line= {{ item.var }} => {{ item.value }}," + regexp='^(\\s*{{ item.var }}\\s*=>\\s*)' + line=' {{ item.var }} => {{ item.value }},' owner=root group=root mode=0644 with_items: - # See /usr/share/doc/gitolite3/README.txt.gz - - { var: UMASK, value: "0027" } - - { var: GIT_CONFIG_KEYS, value: "'gitweb\\..* gc\\..*'" } + # See /usr/share/doc/gitolite3/README.markdown.gz + - { var: UMASK, value: "0027" } + - { var: GIT_CONFIG_KEYS, value: "'gitweb\\..* gc\\..* hook\\..*'" } diff --git a/roles/git/tasks/main.yml b/roles/git/tasks/main.yml index da9f876..f65824e 100644 --- a/roles/git/tasks/main.yml +++ b/roles/git/tasks/main.yml @@ -1,2 +1,4 @@ -- include: gitolite.yml tags=gitolite -- include: cgit.yml tags=cgit +- import_tasks: gitolite.yml + tags: gitolite +- import_tasks: cgit.yml + tags: cgit diff --git a/roles/git/templates/etc/nginx/snippets/git.fripost.org.hpkp-hdr.j2 b/roles/git/templates/etc/nginx/snippets/git.fripost.org.hpkp-hdr.j2 new file mode 120000 index 0000000..a8ba598 --- /dev/null +++ b/roles/git/templates/etc/nginx/snippets/git.fripost.org.hpkp-hdr.j2 @@ -0,0 +1 @@ +../../../../../../certs/hpkp-hdr.j2
\ No newline at end of file |