From e6359a9ceb5fba89ab0d152ce6ead2da7b8afa57 Mon Sep 17 00:00:00 2001 From: memdmp Date: Fri, 3 Jan 2025 01:03:27 +0100 Subject: feat: a sensible setup, for once --- .dockerignore | 1 + .env.example | 1 + .gitignore | 2 + Dockerfile | 133 ++++++++++------------ README.md | 257 ++----------------------------------------- cgitrc | 119 -------------------- compose.yml | 17 +++ contrib/build | 6 + contrib/launch | 4 + contrib/setup-img | 38 +++++++ httpd.conf | 54 --------- image/Caddyfile | 26 +++++ image/cgitrc | 119 ++++++++++++++++++++ image/fcgiwrap-launcher | 15 +++ image/prepare-container.sh | 57 ++++++++++ image/sshd_config | 118 ++++++++++++++++++++ image/syntax-highlighting.sh | 121 ++++++++++++++++++++ prepare-container.sh | 63 ----------- sshd_config | 117 -------------------- 19 files changed, 594 insertions(+), 674 deletions(-) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore delete mode 100644 cgitrc create mode 100644 compose.yml create mode 100755 contrib/build create mode 100755 contrib/launch create mode 100755 contrib/setup-img delete mode 100644 httpd.conf create mode 100644 image/Caddyfile create mode 100644 image/cgitrc create mode 100755 image/fcgiwrap-launcher create mode 100755 image/prepare-container.sh create mode 100644 image/sshd_config create mode 100644 image/syntax-highlighting.sh delete mode 100755 prepare-container.sh delete mode 100644 sshd_config diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cc63de3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +/cgit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2706789 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +SSH_KEY="ssh-ed25519 AAAAC4Ms4C1ZDI1NTE5AAAAIPFc91ReTcvSEkHhtpA9esUOzeXBb7FvuUxbJGUWuDC6 lain@rain" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba8c1d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/cgit +/.env diff --git a/Dockerfile b/Dockerfile index f49018e..858e237 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,92 +1,79 @@ -FROM httpd:2.4-alpine - -MAINTAINER Grégory J. - -WORKDIR /root - -ARG HTTP_PROXY +FROM docker.io/alpine:latest AS base WORKDIR /root # Packages we'll keep -RUN apk update && apk add git openssh && \ - apk add python3 py3-pygments && \ - apk add py3-markdown && \ - apk add libintl musl-libintl && \ - apk add zlib - -# cgit install -RUN git clone git://git.zx2c4.com/cgit -WORKDIR cgit -# Packages needed for build -RUN apk update && apk add gcc make libressl-dev && \ - apk add linux-headers && \ - ln -sf /usr/include/linux/unistd.h /usr/include/ && \ - apk add musl-dev zlib-dev && \ -# Build - git submodule init && \ - git submodule update && \ - make install NO_LUA=1 NO_REGEX=NeedsStartEnd && \ -# Clean up - cd ../ && \ - rm -Rf cgit && \ - apk del gcc make libressl-dev && \ - apk del linux-headers musl-dev zlib-dev && \ - rm -rf /tmp/* /var/cache/apk/* -WORKDIR /root - -# cgit config -ENV HTTP_AUTH_USER="", HTTP_AUTH_PASSWORD="" -ADD httpd.conf /usr/local/apache2/conf/httpd.conf -ADD cgitrc /home/git/cgitrc -# Extra copy if /home/git is bindmounted -ADD cgitrc /etc/cgitrc.default -RUN ln -s /home/git/cgitrc /etc/cgitrc - -# Gitolite install -# Clone -RUN git clone https://github.com/sitaramc/gitolite && \ - gitolite/install -to /usr/local/bin/ +RUN apk upgrade --no-cache && \ + apk add --no-cache \ + git openssh \ + python3 py3-pygments \ + py3-markdown \ + libintl musl-libintl \ + zlib \ + caddy \ + cgit gitolite \ + openssl \ + dumb-init \ + fcgiwrap \ + sudo zsh openrc \ + libcap + +ADD image/prepare-container.sh /usr/local/bin/prepare-container.sh +ADD image/fcgiwrap-launcher /usr/local/bin/fcgiwrap-launcher +RUN chmod +x /usr/local/bin/prepare-container.sh /usr/local/bin/fcgiwrap-launcher -# Default work dir for base image httpd -WORKDIR /usr/local/apache2 +# SSHD config : no password, no strict mode +# Moved by prepare-container.sh +ADD image/sshd_config /etc/sshd_config -# Pre-launch script -ADD prepare-container.sh /usr/local/bin -RUN chmod +x /usr/local/bin/prepare-container.sh +# CGIT Config +# Copied by prepare-container.sh +ADD image/cgitrc /etc/cgitrc.default -# SSHD config : no password, no strict mode -ADD sshd_config /etc/ssh/sshd_config +# Caddy config +ADD image/Caddyfile /etc/caddy/Caddyfile # Remove SSH keyes, fresh keys will be generated at container startup by prepare-container.sh RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key # Gitolis / Gitolite -RUN adduser -D -g "" -s "/bin/ash" git +RUN adduser -D -g "" -s "/bin/ash" http +RUN addgroup git www-data && addgroup git http +RUN addgroup http www-data && addgroup http git # We need a password set, otherwise pubkey auth doesn't work... why ?? /sbin/nologin doesn't work either -RUN echo "git:fhzefGG65gdoejdK$!dhd753" | chpasswd +RUN echo "git:$(openssl rand -hex 4096)" | chpasswd -# Volume for server key -VOLUME ["/etc/ssh"] +# Caddy needs CAP_NET_BIND_SERVICE +RUN setcap CAP_NET_BIND_SERVICE=+eip /usr/sbin/caddy -# Volume for /home/git -VOLUME ["/home/git"] +RUN ln -s /var/lib/git/cgitrc /etc/cgitrc -# Ports +# SSH Keys, Config +VOLUME ["/etc/ssh"] +# Git Directories +VOLUME ["/var/lib/git"] + +# CGit EXPOSE 80 +# SSH EXPOSE 22 -# Minimal INIT system, cf https://github.com/Yelp/dumb-init/ -ADD https://github.com/Yelp/dumb-init/releases/download/v1.0.0/dumb-init_1.0.0_amd64 /usr/local/bin/dumb-init -RUN chmod +x /usr/local/bin/dumb-init - -# Runs "/usr/bin/dumb-init -- sh -c prepare-container.sh && exec apachectl -DFOREGROUND" -# dumb-init gets PID 1 and handles signals gracefully -ENTRYPOINT ["/usr/local/bin/dumb-init", "--"] -CMD ["sh", "-c", "prepare-container.sh && exec httpd-foreground"] - -# To work without dumb-init, uncomment last line in prepare-container.sh to make it usual Docker entrypoint. -# Use following CMD statement which comes from httpd Dockerfile. -# Comment previous ENTRYPOINT and CMD. -#ENTRYPOINT ["prepare-container.sh"] -#CMD ["httpd-foreground"] +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["sh", "-c", "/usr/local/bin/prepare-container.sh && sh -c 'sleep 3 && chgrp www-data /run/fcgiwrap/fcgiwrap.sock && chmod g+w /run/fcgiwrap/fcgiwrap.sock && exec sudo -u http /usr/sbin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile' & /usr/local/bin/fcgiwrap-launcher"] + +FROM base AS with-fmt +RUN apk add --no-cache py3-markdown py3-docutils groff +RUN echo 'about-filter=/usr/lib/cgit/filters/about-formatting.sh\ +readme=:README.rst\ +readme=:readme.rst\ +readme=:README.md\ +readme=:readme.md\ +readme=:README\ +readme=:readme\ +' >> /etc/cgitrc.default + +FROM with-fmt AS with-highlighting +RUN apk add --no-cache highlight +ADD image/syntax-highlighting.sh /usr/lib/cgit/filters/syntax-highlighting-uwu.sh +RUN chmod +x /usr/lib/cgit/filters/syntax-highlighting-uwu.sh +RUN echo 'source-filter=/usr/lib/cgit/filters/syntax-highlighting-uwu.sh' >> /etc/cgitrc.default diff --git a/README.md b/README.md index acee003..7d97069 100644 --- a/README.md +++ b/README.md @@ -1,252 +1,13 @@ -Image docker Gitolite/cgit -========================= +# cgit+caddy+gitolite on alpine in podman -This [Docker][docker] image offers a very quick way of deploying a Gitolite / Cgit server. Gitolite is a lightweight yet powerful git manager. Cgit is web-based frontend to Git repositories. +## installation -Based on Alpine Linux. - - - -## Starting a gitolite-cgit container - -### First launch +1. copy .env.example to .env +2. replace the key with your ssh key +3. run `podman compose up -d --build` +4. rerun the above command without `--build` +5. enjoy -This first launch will create the server RSA keypair and make Gitolite initialization. `SSH_KEY` is the Gitolite admin's public RSA key. -For more details about Gitolite setup, please read the [official documentation][gitolite_doc]. +## setup -The container will stop by itself once the initial configuration is done. The `--rm` will make Docker remove it automatically. Only data will remain on the volume/bindmount. - - $ docker run --rm -dit -v git-data:/home/git -v git-ssh:/etc/ssh -e SSH_KEY="$(cat /home//.ssh/id_rsa.pub)" gjbs84/gitolite-cgit:latest - -Default behavion is to save data into an internal named volume, `git-data` and `git-ssh` in this exemple. Of course you can change it if you wish. - -If it's suits you better you can use a bindmount. Here an exemple with `/srv/git-data` and `/srv/git-ssh`. No existing `repositories` directory must be there ! - - $ docker run --rm -dit -v /srv/git-data:/home/git -v /srv/git-ssh:/etc/ssh -e SSH_KEY="$(cat /home//.ssh/id_rsa.pub)" gjbs84/gitolite-cgit:latest - - -### Troubleshooting - -If the initial startup fails, it can be usefull to repeat it one more time without the `--rm` option. - -The container will remains in stoped state and its logs will be available. - - $ docker logs git-test - -A good first startup looks like this : - -```sh - Generating public/private rsa key pair. - Your identification has been saved in /etc/ssh/ssh_host_rsa_key - Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub - The key fingerprint is: - SHA256:4GcKIlWTPI5tpto3eqfHK30jBqM8U+eWoTp/tWSU2zs root@67dc97f12dd3 - The key's randomart image is: - +---[RSA 3072]----+ - | .o. | - | .+. | - | .+ .. . | - | .. =. .o | - |. .+. ..So | - | ...+.o+= . | - | + o O.* . . | - |. B * % + E | - | oXoX.+ . . | - +----[SHA256]-----+ - Generating public/private dsa key pair. - Your identification has been saved in /etc/ssh/ssh_host_dsa_key - Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub - The key fingerprint is: - SHA256:M5WtzLCBRcU6HtrRdBgOHvDkqa+DU3x5XaWC6VjXexU root@67dc97f12dd3 - The key's randomart image is: - +---[DSA 1024]----+ - | .o*ooo | - | B =+o. E.| - | . B+++.. o.| - | .=B=.o + .| - | ..+SO+o o ..| - | +.*oo . . .| - | o ... . | - | o .. | - | ... | - +----[SHA256]-----+ - Starting sshd - Initialized empty Git repository in /home/git/repositories/gitolite-admin.git/ - Initialized empty Git repository in /home/git/repositories/testing.git/ - WARNING: /home/git/.ssh missing; creating a new one - (this is normal on a brand new install) - WARNING: /home/git/.ssh/authorized_keys missing; creating a new one - (this is normal on a brand new install) - First launch : container is now shut down -``` - -## Final launch - -You can now run the final container. It will use the previoulsy created volumes `git-data` and `git-ssh`. Now we can give a name to this container and we have to NAT ports 22 et 80 to the host. Of course you may have to adapt the command line to your network. - - $ docker run --name gitolite-cgit-srv -dit -v git-data:/home/git -v git-ssh:/etc/ssh -p 20080:80 -p 20022:22 gjbs84/gitolite-cgit:lastest - -If you have chosen the bindmount way : - - $ docker run --name gitolite-cgit-srv -dit -v /srv/git-data:/home/git -v /srv/git-ssh:/etc/ssh -p 20080:80 -p 20022:22 gjbs84/gitolite-cgit:lastest - -It's now time to check if everythings is right ! Let's clone the `testing` repository. - -If you are new to Gitolite you have to know that every connection to it is made by the same user, commonly `git`. A very convenient way to proceed is to add an entry in your `~/.ssh/config` : - - Host - Port 20022 - User git - IdentityFile ~/.ssh/id_rsa - -Of course you have to adapt this to your network once again. - -Now you can easily clone the testing repo : - - $ git clone localhost:testing - Cloning into 'testing'... - Enter passphrase for key '/home/greg/.ssh/id_rsa': - warning: warning: You appear to have cloned an empty repository. - Checking connectivity... done. - -Git tells us this an empty repository, it's true so everything is fine so far. - -## Updating / recreating container - -If you have deleted the exiting container or wish to update it with a newer version, just run the "Final launch" step again. All your data are kept in Docker volume (or bindmount) . - -### .htaccess authentication - -You may wish to protect access to the git fronted Cgit. - -Just give fill up environnement variables `HTTP_AUTH_USER` and `HTTP_AUTH_PASSWORD` during the final launch step : - - $ docker run --name gitolite-cgit-srv -dit -v git-data:/home/git -v git-ssh:/etc/ssh -p 20080:80 -p 20022:22 -e HTTP_AUTH_USER="my_user" -e HTTP_AUTH_PASSWORD="my_password" gjbs84/gitolite-cgit:latest - - -### Troubleshooting - -If you're experimenting some issue, start with having a loog into running container. Check health of `httpd` and `sshd` daemons. - -To jump into the container : - - $ docker exec -ti git-test sh - -Then check for `sshd` and `httpd` : - -``` - $ ps - PID USER TIME COMMAND - 1 root 0:00 /usr/local/bin/dumb-init -- sh -c prepare-container.sh && exec httpd-foreground - 6 root 0:00 httpd -DFOREGROUND - 13 root 0:00 sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups - 69 daemon 0:00 httpd -DFOREGROUND - 70 daemon 0:00 httpd -DFOREGROUND - 71 daemon 0:00 httpd -DFOREGROUND - 72 daemon 0:00 httpd -DFOREGROUND - 73 daemon 0:00 httpd -DFOREGROUND -``` - -## Using Gitolite and Cgit - -### Cgit - -Cgit is configured to automatically serve every repositories located into `/home/git/repositories` which is where Gitolite stores them. You basically have nothing to do to use it, just got to (adapt URL to the port number and server name) : - - http(s)://myserver:20080 - -You may want to custumize it (clone-prefix, favicon, headers...), just edit `/home/git/cgitrc`. - - -### Gitolite - -This is not a Git/Gitolite course, but here is a very simple set of commands to quickly add a new repo to Gitolite. And a new non-admin user in the process. - -1. Clone the `gitolite-admin` repository : - - $ git clone myserver:gitolite-admin - -2. Edit the `conf/gitolite.conf` file to add a repo : - - repo new_repo - RW+ = bob - -3. Add Bob's public RSA key in `keydir/bob.pub` (of course you can use `admin` which already exists but it's not recommanded...). That's all you have to do to add a Gitolite user. - -4. Add, commit and push the updated Gitolite configuration : - - $ git add keydir/bob.pub conf/gitolite.conf - $ git commit -m "Added Bob and new_repo" - $ git push --all - -5. Now just add a remote site in you local `new_repo` repository and push a local branch to it ! - - $ git remote add origin ssh://myserver:new_repo.git - $ git push origin master - - -For more details, you'll have to check for official documentation of both projects ! - - * [Gitolite][gitolite_admin] administration - * [Cgit][cgit_page] - - -## Add existing repositories - -First you must have an archive containing all you existing repositories. - -They have to be BARE repositories ! No working copy should exist in any of them ! - -1. Jump into the container - -2. Copy repos archive into the container. - - $ scp user@:/home/user/repos.tgz /tmp/ - -3. Untar archive into Gitolite repositories directory : - - $ cd /home/git/repositories - $ tar -xf /tmp/repos.tgz - $ rm /tmp/repos.tgz - -4. Set permissions : - - $ chown -R git:git * - $ chmod -R 755 * - -5. From now you definitely should read [the official procedure][gitolite_existing_repo] before you go any further ! These commands come directly from there. - - $ su git - $ cd - $ gitolite compile - $ gitolite setup --hooks-only - $ gitolite trigger POST_COMPILE - -6. Clone the Gitolite admin repository or go to your local copy and update the `gitolite.conf` with your new repositories info. Don't forget to add new users public key in `keydir` if needed. - -7. Add/commit/push and you're done ! Check everything is fine with the `info` command. You shoud see all the repositories you have access to, which means all of them (because you have the admin key). - - $ ssh git@myserver info - -8. Adjust Cgit configuration in `/home/git/cgitrc` if you wish, but it will work out of the box. - - -## Building container image - -In case you want to build you own image, clone from Github and build using the common Docker way (adjust or remove proxy settings according to your needs). - - $ docker build --build-arg HTTP_PROXY=http://192.168.0.1:3128 -t . - - -## Voir aussi - -* [Base image I used (httpd 2.4) ](https:https://hub.docker.com/_/httpd) -* [Gitolite image](http://github.com/sitaramc/gitolite#adding-users-and-repos) -* [Cgit image](https://github.com/invokr/docker-cgit) -* [Gitolite Documentation](https://gitolite.com/gitolite/index.html) - -[docker]: https://www.docker.com/ -[gitolite_doc]: https://gitolite.com/gitolite/install.html -[gitolite_admin]: https://gitolite.com/gitolite/basic-admin.html -[cgit_page]: https://git.zx2c4.com/cgit/about/ -[gitolite_existing_repo]: https://gitolite.com/gitolite/basic-admin.html#appendix-1-bringing-existing-repos-into-gitolite +to [clone the admin repo](https://gitolite.com/gitolite/basic-admin.html#clone-the-gitolite-admin-repo), run `git clone ssh://git@127.0.0.1:12222/gitolite-admin`. diff --git a/cgitrc b/cgitrc deleted file mode 100644 index 4ab1c02..0000000 --- a/cgitrc +++ /dev/null @@ -1,119 +0,0 @@ -# Enable caching of up to 1000 output entries -cache-size=1000 - -# Specify some default clone prefixes -clone-prefix=http://git.mydomain.com/git ssh://git@git.mydomain.com - -# Specify the css url -css=/cgit.css - -# Show extra links for each repository on the index page -enable-index-links=1 - -# Show number of affected files per commit on the log pages -enable-log-filecount=1 - -# Show number of added/removed lines per commit on the log pages -enable-log-linecount=1 - -# Enable ASCII art commit history graph on the log pages -enable-commit-graph=1 - -# Add a cgit favicon -#favicon=/favicon.ico - -# Use a custom logo -logo=/cgit.png - -# Enable statistics per week, month and quarter -max-stats=month - -# Set the title and heading of the repository index page -root-title=Welcome ! - -# Set a subheading for the repository index page -root-desc=Some information... - -# Include some more info about foobar.com on the index page -#root-readme=/var/www/htdocs/about.html - -# Allow download of tar.gz, tar.bz2 and zip-files -snapshots=tar.gz tar.bz2 zip - -robots=noindex, nofollow -enable-git-config=1 -#source-filter=/opt/highlight.sh -source-filter=/usr/local/lib/cgit/filters/syntax-highlighting.py - - -## -## Search for these files in the root of the default branch of repositories -## for coming up with the about page: -## -readme=:README.md -readme=:readme.md -readme=:README.mkd -readme=:readme.mkd -readme=:README.rst -readme=:readme.rst -readme=:README.html -readme=:readme.html -readme=:README.htm -readme=:readme.htm -readme=:README.txt -readme=:readme.txt -readme=:README -readme=:readme -readme=:INSTALL.md -readme=:install.md -readme=:INSTALL.mkd -readme=:install.mkd -readme=:INSTALL.rst -readme=:install.rst -readme=:INSTALL.html -readme=:install.html -readme=:INSTALL.htm -readme=:install.htm -readme=:INSTALL.txt -readme=:install.txt -readme=:INSTALL -readme=:install - -about-filter=/usr/local/lib/cgit/filters/about-formatting.sh - -## -### List of common mimetypes -### - -mimetype.git=image/git -mimetype.html=text/html -mimetype.jpg=image/jpeg -mimetype.jpeg=image/jpeg -mimetype.pdf=application/pdf -mimetype.png=image/png -mimetype.svg=image/svg+xml - -## -## List of repositories. -## PS: Any repositories listed when repo.group is unset will not be -## displayed under a group heading -## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') -## and included like this: -## include=/etc/cgitrepos -## - -#### -section=my repo - -#repo.url=testing -#repo.path=/home/git/testing.git -#repo.desc=Testing repo created by Gitolite -#repo.owner=admin@mynetwork.com -# - - - -# Auto scan -scan-path=/home/git/repositories - - diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..e3359f2 --- /dev/null +++ b/compose.yml @@ -0,0 +1,17 @@ +services: + cgit: + image: docker.io/memdmp/cgit:local-build + build: + dockerfile: ./Dockerfile + volumes: + - cgit_ssh:/etc/ssh:rw + - ./cgit/repos:/var/lib/git:rw + ports: + - 127.0.0.1:18080:80 + - 127.0.0.1:12222:22 + env_file: + - .env + +volumes: + cgit_ssh: + cgit_repos: diff --git a/contrib/build b/contrib/build new file mode 100755 index 0000000..f071a5d --- /dev/null +++ b/contrib/build @@ -0,0 +1,6 @@ +#!/bin/zsh +set -eax +IMG="${IMG:-"docker.io/memdmp/cgit:${TAG:-"local-build"}"}" +! podman container exists cgit >/dev/null 2>/dev/null || podman container rm cgit +! podman image exists "$IMG" >/dev/null 2>/dev/null || podman image rm "$IMG" +podman build -t "$IMG" . diff --git a/contrib/launch b/contrib/launch new file mode 100755 index 0000000..0124c70 --- /dev/null +++ b/contrib/launch @@ -0,0 +1,4 @@ +#!/bin/zsh +set -eax +podman container exists cgit || ("$(dirname "$(realpath "$0")")/setup-img" 2>&1 | tee /tmp/setup || (grep 'First launch: container is now shut down' /tmp/setup && rm /tmp/setup)) +podman start -ia cgit diff --git a/contrib/setup-img b/contrib/setup-img new file mode 100755 index 0000000..879f383 --- /dev/null +++ b/contrib/setup-img @@ -0,0 +1,38 @@ +#!/bin/zsh +set -eax + +__filename="$(realpath "$0")" +__dirname="$(dirname "${__filename})" +if [[ -f "$__dirname/.env" ]]; then + source "$__dirname/.env" +fi + +IMG="${IMG:-"docker.io/memdmp/cgit:${TAG:-"local-build"}"}" +SSH_DIR="${SSH_DIR:-"$HOME/.ssh"}" +SSH_KEY="${SSH_KEY:-"$(ls "$SSH_DIR/id_*.pub" | head -n 1)"}" +if [[ -f "$SSH_KEY" ]]; then + SSH_KEY="$(cat "$SSH_KEY")" +elif [[ -f "$SSH_DIR/$SSH_KEY.pub" ]]; then + SSH_KEY="$(cat "$SSH_DIR/$SSH_KEY.pub")" +elif [[ -f "$SSH_DIR/id_$SSH_KEY.pub" ]]; then + SSH_KEY="$(cat "$SSH_DIR/id_$SSH_KEY.pub")" +elif [[ -f "$SSH_DIR/$SSH_KEY" ]]; then + SSH_KEY="$(cat "$SSH_DIR/$SSH_KEY")" +elif [[ -f "$SSH_DIR/id_$SSH_KEY" ]]; then + SSH_KEY="$(cat "$SSH_DIR/id_$SSH_KEY")" +fi + +mkdir -p cgit/{ssh,git} +! podman container exists cgit >/dev/null 2>/dev/null || podman container rm cgit +! podman network exists cgit >/dev/null 2>/dev/null || podman network rm cgit +podman network create cgit +podman create \ + --name cgit \ + --network cgit \ + -v "$(pwd)/cgit/ssh:/etc/ssh:rw" \ + -v "$(pwd)/cgit/git:/var/lib/git:rw" \ + -p 127.0.0.1:18080:80 \ + -p 127.0.0.1:12222:22 \ + -e "SSH_KEY=${SSH_KEY}" \ + "$IMG" "$@" +podman start -ia cgit diff --git a/httpd.conf b/httpd.conf deleted file mode 100644 index dc6c934..0000000 --- a/httpd.conf +++ /dev/null @@ -1,54 +0,0 @@ -ServerRoot "/usr/local/apache2" - -# standard -LoadModule authz_core_module modules/mod_authz_core.so -LoadModule unixd_module modules/mod_unixd.so -LoadModule log_config_module modules/mod_log_config.so -LoadModule logio_module modules/mod_logio.so -LoadModule mime_magic_module modules/mod_mime_magic.so -LoadModule mime_module modules/mod_mime.so -LoadModule mpm_prefork_module modules/mod_mpm_prefork.so -LoadModule cgi_module modules/mod_cgi.so -LoadModule dir_module modules/mod_dir.so - -# uncomment for htaccess -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule authn_core_module modules/mod_authn_core.so -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authz_user_module modules/mod_authz_user.so - -Listen 80 -User daemon -Group daemon - -ServerName localhost -ServerAdmin root@localhost - -ErrorLog "logs/error_log" -LogLevel warn - -LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined -LogFormat "%h %l %u %t \"%r\" %>s %b" common -CustomLog "logs/access_log" combined - -AddHandler cgi-script .cgi -AddDefaultCharset UTF-8 -TypesConfig conf/mime.types -MIMEMagicFile conf/magic -EnableSendfile on - - - Require all denied - - -DocumentRoot "/var/www/htdocs/cgit" - - DirectoryIndex cgit.cgi - AllowOverride All - Options +ExecCGI -FollowSymLinks - Require all granted - - - - Require all denied - diff --git a/image/Caddyfile b/image/Caddyfile new file mode 100644 index 0000000..b50dccc --- /dev/null +++ b/image/Caddyfile @@ -0,0 +1,26 @@ +http:// { + route { + root * /var/lib/git/static + file_server { + pass_thru + } + } + + route { + root * /usr/share/webapps/cgit + file_server { + pass_thru + } + } + + reverse_proxy unix//run/fcgiwrap/fcgiwrap.sock { + transport fastcgi { + env SCRIPT_FILENAME /usr/share/webapps/cgit/cgit.cgi + env PATH_INFO {http.request.uri} + env QUERY_STRING {query} + # env GIT_HTTP_EXPORT_ALL 1 + # env GIT_PROJECT_ROOT /var/lib/git/repositories + # env HOME /var/lib/git + } + } +} diff --git a/image/cgitrc b/image/cgitrc new file mode 100644 index 0000000..60d0bef --- /dev/null +++ b/image/cgitrc @@ -0,0 +1,119 @@ +# Enable caching of up to 1000 output entries +cache-size=1000 + +# Specify some default clone prefixes +clone-prefix=http://git.mydomain.com/git ssh://git@git.mydomain.com + +# Specify the css url +css=/cgit.css + +# Show extra links for each repository on the index page +enable-index-links=1 + +# Show number of affected files per commit on the log pages +enable-log-filecount=1 + +# Show number of added/removed lines per commit on the log pages +enable-log-linecount=1 + +# Enable ASCII art commit history graph on the log pages +enable-commit-graph=1 + +# Add a cgit favicon +#favicon=/favicon.ico + +# Use a custom logo +logo=/cgit.png + +# Enable statistics per week, month and quarter +max-stats=month + +# Set the title and heading of the repository index page +root-title=Welcome ! + +# Set a subheading for the repository index page +root-desc=Some information... + +# Include some more info about foobar.com on the index page +#root-readme=/var/www/htdocs/about.html + +# Allow download of tar.gz, tar.bz2 and zip-files +snapshots=tar.gz tar.bz2 zip + +robots=noindex, nofollow +enable-git-config=1 +#source-filter=/opt/highlight.sh +source-filter=/usr/local/lib/cgit/filters/syntax-highlighting.py + + +## +## Search for these files in the root of the default branch of repositories +## for coming up with the about page: +## +readme=:README.md +readme=:readme.md +readme=:README.mkd +readme=:readme.mkd +readme=:README.rst +readme=:readme.rst +readme=:README.html +readme=:readme.html +readme=:README.htm +readme=:readme.htm +readme=:README.txt +readme=:readme.txt +readme=:README +readme=:readme +readme=:INSTALL.md +readme=:install.md +readme=:INSTALL.mkd +readme=:install.mkd +readme=:INSTALL.rst +readme=:install.rst +readme=:INSTALL.html +readme=:install.html +readme=:INSTALL.htm +readme=:install.htm +readme=:INSTALL.txt +readme=:install.txt +readme=:INSTALL +readme=:install + +about-filter=/usr/local/lib/cgit/filters/about-formatting.sh + +## +### List of common mimetypes +### + +mimetype.git=image/git +mimetype.html=text/html +mimetype.jpg=image/jpeg +mimetype.jpeg=image/jpeg +mimetype.pdf=application/pdf +mimetype.png=image/png +mimetype.svg=image/svg+xml + +## +## List of repositories. +## PS: Any repositories listed when repo.group is unset will not be +## displayed under a group heading +## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') +## and included like this: +## include=/etc/cgitrepos +## + +#### +section=my repo + +#repo.url=testing +#repo.path=/var/lib/git/testing.git +#repo.desc=Testing repo created by Gitolite +#repo.owner=admin@mynetwork.com +# + + + +# Auto scan +scan-path=/var/lib/git/repositories + + diff --git a/image/fcgiwrap-launcher b/image/fcgiwrap-launcher new file mode 100755 index 0000000..0970ec4 --- /dev/null +++ b/image/fcgiwrap-launcher @@ -0,0 +1,15 @@ +#!/bin/zsh +set -eax +command="/usr/bin/fcgiwrap" +user="fcgiwrap" +group="www-data" +: ${socket:="unix:/run/fcgiwrap/fcgiwrap.sock"} +case "$socket" in +unix:/*) + local socket_path="${socket#unix:}" + /usr/libexec/rc/bin/checkpath --directory --mode 2775 --owner "${user}:${group}" \ + "${socket_path%/*}" + ;; +esac + +exec sudo -u "$user" -g "$group" "$command" -c "${nproc:-$(nproc)}" -s "$socket" diff --git a/image/prepare-container.sh b/image/prepare-container.sh new file mode 100755 index 0000000..66ccb2f --- /dev/null +++ b/image/prepare-container.sh @@ -0,0 +1,57 @@ +#!/bin/sh +set -e + +# Warning : this no standard docker entrypoint, we use dumb-init ! +ensureKeyAlgo() { + if [ ! -f "/etc/ssh/ssh_host_${1}_key" ]; then + # generate fresh $1 key + ssh-keygen -f /etc/ssh/ssh_host_${1}_key -N '' -t "${1}" + fi +} +ensureKeyAlgo ed25519 +ensureKeyAlgo rsa +ensureKeyAlgo ecdsa +[[ -f /etc/sshd_config ]] && mv /etc/sshd_config /etc/ssh/sshd_config || [[ -f /etc/ssh/sshd_config ]] +chmod -w /etc/ssh/sshd_config + +# prepare run dir +if ! [[ -d "/var/run/sshd" ]]; then + mkdir -p /var/run/sshd +fi + +# Run sshd +echo "Starting sshd" +/usr/sbin/sshd + +# Volume permissions +echo "Setting up permissions" +mkdir -p /var/lib/git/.gitolite/logs +chown -R git /var/lib/git +chgrp -R www-data /var/lib/git +chmod -R 775 /var/lib/git + +# If no cgitrc, let's copy one from /etc/cgitrc.default. This happens when bindmounting /var/lib/git +if [ ! -f "/var/lib/git/cgitrc" ]; then + echo '# This is an autogenrated file. Do not edit it by hand, changes will be lost.' | cat - /etc/cgitrc.default > /var/lib/git/cgitrc + chown git /var/lib/git/cgitrc + chmod 711 /var/lib/git/cgitrc +fi +if [ ! -f "/var/lib/git/.ssh/authorized_keys" ]; then + # Gitolite configuration (admin pubkey) + if [ -n "$SSH_KEY" ]; then + echo "$SSH_KEY" > "/tmp/admin.pub" + su - git -c "gitolite setup -pk \"/tmp/admin.pub\"" + rm "/tmp/admin.pub" + else + echo "You need to specify SSH_KEY on first run to setup gitolite" + echo 'Example: podman run --rm -dit -v git-data:/var/lib/git -v git-ssh:/etc/ssh -e SSH_KEY="$(cat /home//.ssh/id_rsa.pub)" gjbs84/gitolite-cgit:latest' + exit 1 + fi + echo "First launch: container is now shut down" + halt +else + # Check setup at every startup + su - git -c "gitolite setup" +fi + +#exec "$@" diff --git a/image/sshd_config b/image/sshd_config new file mode 100644 index 0000000..553d298 --- /dev/null +++ b/image/sshd_config @@ -0,0 +1,118 @@ +# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/bin:/usr/bin:/sbin:/usr/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options override the +# default value. + +#Port 22 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key + +# Ciphers and keying +#RekeyLimit default none + +# Logging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +#PermitRootLogin prohibit-password +StrictModes no +#MaxAuthTries 6 +#MaxSessions 10 + +#PubkeyAuthentication yes + +# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 +# but this is overridden so installations will only check .ssh/authorized_keys +AuthorizedKeysFile .ssh/authorized_keys + +#AuthorizedPrincipalsFile none + +#AuthorizedKeysCommand none +#AuthorizedKeysCommandUser nobody + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication no +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +#ChallengeResponseAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +#UsePAM no + +#AllowAgentForwarding yes +# Feel free to re-enable these if your use case requires them. +AllowTcpForwarding no +GatewayPorts no +X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PermitTTY yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS no +#PidFile /run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# override default of no subsystems +Subsystem sftp /usr/lib/ssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# PermitTTY no +# ForceCommand cvs server diff --git a/image/syntax-highlighting.sh b/image/syntax-highlighting.sh new file mode 100644 index 0000000..3de95fa --- /dev/null +++ b/image/syntax-highlighting.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# This script can be used to implement syntax highlighting in the cgit +# tree-view by referring to this file with the source-filter or repo.source- +# filter options in cgitrc. +# +# This script requires a shell supporting the ${var##pattern} syntax. +# It is supported by at least dash and bash, however busybox environments +# might have to use an external call to sed instead. +# +# Note: the highlight command (http://www.andre-simon.de/) uses css for syntax +# highlighting, so you'll probably want something like the following included +# in your css file: +# +# Style definition file generated by highlight 2.4.8, http://www.andre-simon.de/ +# +# table.blob .num { color:#2928ff; } +# table.blob .esc { color:#ff00ff; } +# table.blob .str { color:#ff0000; } +# table.blob .dstr { color:#818100; } +# table.blob .slc { color:#838183; font-style:italic; } +# table.blob .com { color:#838183; font-style:italic; } +# table.blob .dir { color:#008200; } +# table.blob .sym { color:#000000; } +# table.blob .kwa { color:#000000; font-weight:bold; } +# table.blob .kwb { color:#830000; } +# table.blob .kwc { color:#000000; font-weight:bold; } +# table.blob .kwd { color:#010181; } +# +# +# Style definition file generated by highlight 2.6.14, http://www.andre-simon.de/ +# +# body.hl { background-color:#ffffff; } +# pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';} +# .hl.num { color:#2928ff; } +# .hl.esc { color:#ff00ff; } +# .hl.str { color:#ff0000; } +# .hl.dstr { color:#818100; } +# .hl.slc { color:#838183; font-style:italic; } +# .hl.com { color:#838183; font-style:italic; } +# .hl.dir { color:#008200; } +# .hl.sym { color:#000000; } +# .hl.line { color:#555555; } +# .hl.mark { background-color:#ffffbb;} +# .hl.kwa { color:#000000; font-weight:bold; } +# .hl.kwb { color:#830000; } +# .hl.kwc { color:#000000; font-weight:bold; } +# .hl.kwd { color:#010181; } +# +# +# Style definition file generated by highlight 3.8, http://www.andre-simon.de/ +# +# body.hl { background-color:#e0eaee; } +# pre.hl { color:#000000; background-color:#e0eaee; font-size:10pt; font-family:'Courier New';} +# .hl.num { color:#b07e00; } +# .hl.esc { color:#ff00ff; } +# .hl.str { color:#bf0303; } +# .hl.pps { color:#818100; } +# .hl.slc { color:#838183; font-style:italic; } +# .hl.com { color:#838183; font-style:italic; } +# .hl.ppc { color:#008200; } +# .hl.opt { color:#000000; } +# .hl.lin { color:#555555; } +# .hl.kwa { color:#000000; font-weight:bold; } +# .hl.kwb { color:#0057ae; } +# .hl.kwc { color:#000000; font-weight:bold; } +# .hl.kwd { color:#010181; } +# +# +# Style definition file generated by highlight 3.13, http://www.andre-simon.de/ +# +# body.hl { background-color:#e0eaee; } +# pre.hl { color:#000000; background-color:#e0eaee; font-size:10pt; font-family:'Courier New',monospace;} +# .hl.num { color:#b07e00; } +# .hl.esc { color:#ff00ff; } +# .hl.str { color:#bf0303; } +# .hl.pps { color:#818100; } +# .hl.slc { color:#838183; font-style:italic; } +# .hl.com { color:#838183; font-style:italic; } +# .hl.ppc { color:#008200; } +# .hl.opt { color:#000000; } +# .hl.ipl { color:#0057ae; } +# .hl.lin { color:#555555; } +# .hl.kwa { color:#000000; font-weight:bold; } +# .hl.kwb { color:#0057ae; } +# .hl.kwc { color:#000000; font-weight:bold; } +# .hl.kwd { color:#010181; } +# +# +# The following environment variables can be used to retrieve the configuration +# of the repository for which this script is called: +# CGIT_REPO_URL ( = repo.url setting ) +# CGIT_REPO_NAME ( = repo.name setting ) +# CGIT_REPO_PATH ( = repo.path setting ) +# CGIT_REPO_OWNER ( = repo.owner setting ) +# CGIT_REPO_DEFBRANCH ( = repo.defbranch setting ) +# CGIT_REPO_SECTION ( = section setting ) +# CGIT_REPO_CLONE_URL ( = repo.clone-url setting ) +# + +# store filename and extension in local vars +BASENAME="$1" +EXTENSION="${BASENAME##*.}" + +[ "${BASENAME}" = "${EXTENSION}" ] && EXTENSION=txt +[ -z "${EXTENSION}" ] && EXTENSION=txt + +# map Makefile and Makefile.* to .mk +[ "${BASENAME%%.*}" = "Makefile" ] && EXTENSION=mk + +# highlight versions 2 and 3 have different commandline options. Specifically, +# the -X option that is used for version 2 is replaced by the -O xhtml option +# for version 3. +# +# Version 2 can be found (for example) on EPEL 5, while version 3 can be +# found (for example) on EPEL 6. +# +# This is for version 2 +#exec highlight --force -f -I -X -S "$EXTENSION" 2>/dev/null + +# This is for version 3 +exec highlight --force --inline-css -f -I -O xhtml -S "$EXTENSION" 2>/dev/null diff --git a/prepare-container.sh b/prepare-container.sh deleted file mode 100755 index da8544d..0000000 --- a/prepare-container.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh - -# Warning : this no standard docker entrypoint, we use dumb-init ! - -if [ ! -f "/etc/ssh/ssh_host_rsa_key" ]; then - # generate fresh rsa key - ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa -fi -if [ ! -f "/etc/ssh/ssh_host_dsa_key" ]; then - # generate fresh dsa key - ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa -fi - -#prepare run dir -if [ ! -d "/var/run/sshd" ]; then - mkdir -p /var/run/sshd -fi - -# Run sshd -echo "Starting sshd" -/usr/sbin/sshd - -# If no cgitrc, let's copy one from /etc/cgitrc.default. This happens when bindmounting /home/git -if [ ! -f "/home/git/cgitrc" ]; then - cp /etc/cgitrc.default /home/git/cgitrc -fi - -# Gitolite configuration (admin pubkey) -if [ ! -f "/home/git/.ssh/authorized_keys" ]; then - if [ -n "$SSH_KEY" ]; then - echo "$SSH_KEY" > "/tmp/admin.pub" - su - git -c "gitolite setup -pk \"/tmp/admin.pub\"" - rm "/tmp/admin.pub" - else - echo "You need to specify SSH_KEY on first run to setup gitolite" - echo 'Example: docker run --rm -dit -v git-data:/home/git -v git-ssh:/etc/ssh -e SSH_KEY="$(cat /home//.ssh/id_rsa.pub)" gjbs84/gitolite-cgit:latest' - exit 1 - fi - echo "First launch : container is now shut down" - halt -# Check setup at every startup -else - su - git -c "gitolite setup" -fi - -# Volume permissions -echo "Setting up permissions" -chown -R git:git /home/git -chmod -R 755 /home/git/repositories - -# htaccess/htpasswd auth (comes from docker-cgit/scripts) -echo "No Apache htaccess required" -if [ "$HTTP_AUTH_PASSWORD" != "" ]; then - echo "Enables Apache htaccess" - echo "AuthType Basic -AuthName \"CGit\" -AuthUserFile /var/www/htdocs/cgit/.htpasswd -Require valid-user" > /var/www/htdocs/cgit/.htaccess -htpasswd -c -b /var/www/htdocs/cgit/.htpasswd $HTTP_AUTH_USER $HTTP_AUTH_PASSWORD -fi - -#exec "$@" - diff --git a/sshd_config b/sshd_config deleted file mode 100644 index 7f51fe2..0000000 --- a/sshd_config +++ /dev/null @@ -1,117 +0,0 @@ -# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ - -# This is the sshd server system-wide configuration file. See -# sshd_config(5) for more information. - -# This sshd was compiled with PATH=/bin:/usr/bin:/sbin:/usr/sbin - -# The strategy used for options in the default sshd_config shipped with -# OpenSSH is to specify options with their default value where -# possible, but leave them commented. Uncommented options override the -# default value. - -#Port 22 -#AddressFamily any -#ListenAddress 0.0.0.0 -#ListenAddress :: - -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key - -# Ciphers and keying -#RekeyLimit default none - -# Logging -#SyslogFacility AUTH -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -#PermitRootLogin prohibit-password -StrictModes no -#MaxAuthTries 6 -#MaxSessions 10 - -#PubkeyAuthentication yes - -# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 -# but this is overridden so installations will only check .ssh/authorized_keys -AuthorizedKeysFile .ssh/authorized_keys - -#AuthorizedPrincipalsFile none - -#AuthorizedKeysCommand none -#AuthorizedKeysCommandUser nobody - -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -PasswordAuthentication no -#PermitEmptyPasswords no - -# Change to no to disable s/key passwords -#ChallengeResponseAuthentication yes - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the ChallengeResponseAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via ChallengeResponseAuthentication may bypass -# the setting of "PermitRootLogin without-password". -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and ChallengeResponseAuthentication to 'no'. -#UsePAM no - -#AllowAgentForwarding yes -# Feel free to re-enable these if your use case requires them. -AllowTcpForwarding no -GatewayPorts no -X11Forwarding no -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PermitTTY yes -#PrintMotd yes -#PrintLastLog yes -#TCPKeepAlive yes -#PermitUserEnvironment no -#Compression delayed -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS no -#PidFile /run/sshd.pid -#MaxStartups 10:30:100 -#PermitTunnel no -#ChrootDirectory none -#VersionAddendum none - -# no default banner path -#Banner none - -# override default of no subsystems -Subsystem sftp /usr/lib/ssh/sftp-server - -# Example of overriding settings on a per-user basis -#Match User anoncvs -# X11Forwarding no -# AllowTcpForwarding no -# PermitTTY no -# ForceCommand cvs server -- cgit v1.2.3