From 12de316a9883915267cf1de4da9c031e35294d68 Mon Sep 17 00:00:00 2001 From: rohhie Date: Sat, 29 Apr 2023 21:11:49 +0900 Subject: [PATCH] First version --- .gitignore | 5 + 01-setup.sh | 220 ++++++++++ 02-setup-postgres.sh | 5 + 10-hosts.sh | 17 + 91-teardown.sh | 108 +++++ 92-teardown-postgres.sh | 14 + LICENSE | 9 + LICENSE_CA.pl | 6 + README.md | 39 ++ SSL/CA.pl | 243 +++++++++++ SSL/openssl.cnf | 407 ++++++++++++++++++ apache/example.net.conf | 27 ++ apache/gitea.conf | 27 ++ apache/kopano.conf | 30 ++ docker/config/gitea/Dockerfile | 4 + docker/config/kopano/Dockerfile | 50 +++ docker/config/kopano/entrypoint.sh | 64 +++ docker/config/kopano/packages/addfirstuser.sh | 18 + docker/config/kopano/packages/config.sh | 107 +++++ docker/config/mariadb-init/init.sql | 4 + docker/docker-compose.yml | 84 ++++ postgres/docker-compose.yml | 18 + 22 files changed, 1506 insertions(+) create mode 100644 .gitignore create mode 100755 01-setup.sh create mode 100755 02-setup-postgres.sh create mode 100755 10-hosts.sh create mode 100755 91-teardown.sh create mode 100755 92-teardown-postgres.sh create mode 100644 LICENSE create mode 100644 LICENSE_CA.pl create mode 100644 README.md create mode 100755 SSL/CA.pl create mode 100644 SSL/openssl.cnf create mode 100644 apache/example.net.conf create mode 100644 apache/gitea.conf create mode 100644 apache/kopano.conf create mode 100644 docker/config/gitea/Dockerfile create mode 100644 docker/config/kopano/Dockerfile create mode 100755 docker/config/kopano/entrypoint.sh create mode 100755 docker/config/kopano/packages/addfirstuser.sh create mode 100755 docker/config/kopano/packages/config.sh create mode 100644 docker/config/mariadb-init/init.sql create mode 100644 docker/docker-compose.yml create mode 100644 postgres/docker-compose.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27f6302 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +cert/ +*.tar.gz +exampleCA/ +docker/config/gitea/conf/app.ini +.setupphase.txt diff --git a/01-setup.sh b/01-setup.sh new file mode 100755 index 0000000..05a1e36 --- /dev/null +++ b/01-setup.sh @@ -0,0 +1,220 @@ +#!/bin/bash +SCRIPTHOME=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +export SSLHOME=$SCRIPTHOME/SSL + +secho() { + for ((i=0;i<$1;i++)); do echo ""; done + echo $2 +} + +sudo echo -n "" +if [ $(whoami) = "root" ]; then + echo "sudo せずに実行してください" + exit 0 +fi + +echo "0" > $SCRIPTHOME/.setupphase.txt + +echo "================================================" +echo " 認証局の作成" +echo "================================================" +cd $SSLHOME + +./CA.pl -newca + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +secho 3 "=== CA証明書部分を切り出す" +sed -n "/-----BEGIN/,/CERTIFICATE-----/p" exampleCA/cacert.pem > exampleCA/example.net.ca.crt + +secho 3 "=== OSにCA証明書を登録" +sudo cp exampleCA/example.net.ca.crt /usr/local/share/ca-certificates/ +sudo update-ca-certificates + +echo "1" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " SSL証明書の作成" +echo "================================================" +cd exampleCA/certs/ + +echo "=== 証明書署名要求の作成" +SSLCERTDIR=$(date +%Y%m%d%H%M)_wildcard.example.net +mkdir $SSLCERTDIR +cd $SSLCERTDIR +$SSLHOME/CA.pl -newreq + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +secho 3 "=== CAで署名" +$SSLHOME/CA.pl -sign + +secho 3 "=== SSL証明書部分を切り出す" +sed -n "/-----BEGIN/,/CERTIFICATE-----/p" newcert.pem > wildcard.example.net.crt + +secho 3 "=== 秘密鍵からパスフレーズを削除" +openssl pkey -in newkey.pem -out wildcard.example.net.key + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +secho 3 "=== SSL証明書と秘密鍵を配置" +sudo cp wildcard.example.net.crt /etc/ssl/private +sudo cp wildcard.example.net.key /etc/ssl/private + +echo "2" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " Apacheの設定" +echo "================================================" +cd $SCRIPTHOME + +echo "=== Apacheのインストール" +sudo apt -y install apache2 + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +secho 3 "=== サイト設定" +sudo a2dissite 000-default +sudo cp apache/*.conf /etc/apache2/sites-available/ +sudo a2ensite example.net gitea kopano + +secho 3 "=== モジュールの有効化" +sudo a2enmod ssl rewrite proxy_http headers + +secho 3 "=== 警告を止める設定" +echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/fqdn.conf > /dev/null +sudo a2enconf fqdn + +secho 3 "=== Apacheの再起動" +sudo systemctl restart apache2 + +echo "3" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " git接続設定の構成" +echo "================================================" +sudo apt -y install ssh + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +ssh-keygen -t ed25519 -C "$(whoami) git key" -f ~/.ssh/git-key +cat <> ~/.ssh/config +host git.example.net + HostName git.example.net + User $(whoami) + IdentityFile ~/.ssh/git-key +EOF + +echo "4" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " ユーザーgitの作成" +echo "================================================" +sudo useradd -m git + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +echo "=== gitの証明書の作成" +sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key" -f /home/git/.ssh/id_rsa +sudo -u git cp /home/git/.ssh/id_rsa.pub /home/git/.ssh/authorized_keys +sudo -u git chmod 600 /home/git/.ssh/authorized_keys + +echo "=== SSHパススルー用のコマンドを生成" +cat <<"EOF" | sudo tee /usr/local/bin/gitea > /dev/null +#!/bin/sh +ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" +EOF +sudo chmod +x /usr/local/bin/gitea + +echo "5" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " コンテナの起動" +echo "================================================" +cd $SCRIPTHOME/docker + +SSLCERTDIR=$SCRIPTHOME/SSL/exampleCA/certs/$(ls -r ../SSL/exampleCA/certs | head -n1) + +echo "=== 証明書の配置" +if [ ! -d config/kopano/packages/cert ]; then + mkdir config/kopano/packages/cert +fi +cp $SSLCERTDIR/wildcard.example.net.crt config/kopano/packages/cert/server.crt +cp $SSLCERTDIR/wildcard.example.net.key config/kopano/packages/cert/server.key +if [ ! -d config/gitea/cert ]; then + mkdir config/gitea/cert +fi +cp ../SSL/exampleCA/example.net.ca.crt config/gitea/cert/ca.crt + +secho 3 "=== Kopanoパッケージの配置" +echo "Kopano Community Edition の core と webapp をダウンロードして" +echo "$SCRIPTHOME/docker/config/kopano/packagesにコピーしてください。" +echo " core-XX.X.X.XX.XXXXXXX-Ubuntu_20.04-amd64.tar.gz" +echo " webapp-X.X.X.XX.XXXXXXX-Ubuntu_20.04-all.tar.gz" +echo " ※Xはバージョンを表す英数字になっています。" +echo "https://download.kopano.io/community/" +read -p "コピーが終わったらEnterキーを押してください。" + +secho 3 "=== コンテナの起動" +sudo docker compose up -d --build + +if [ $? -ne 0 ]; then + echo "処理を中止します" + exit +fi + +echo "6" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " rvmのインストール" +echo "================================================" +cd $SCRIPTHOME + +sudo apt install gnupg2 +gpg --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +\curl -sSL https://get.rvm.io | bash -s stable + +sed -i '$ a \\n[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*' ~/.bashrc + +if [ $(stat -c %s ~/.bash_profile) -eq 200 ]; then rm ~/.bash_profile; fi +if [ $(stat -c %s ~/.mkshrc) -eq 118 ]; then rm ~/.mkshrc; fi +if [ $(stat -c %s ~/.zlogin) -eq 118 ]; then rm ~/.zlogin; fi +if [ $(stat -c %s ~/.zshrc) -eq 118 ]; then rm ~/.zshrc; fi + +echo "7" > $SCRIPTHOME/.setupphase.txt + +secho 5 +echo "================================================" +echo " hostsの設定" +echo "================================================" + +./10-hosts.sh + +echo "8" > $SCRIPTHOME/.setupphase.txt + +secho 3 "=== セットアップ完了" +exit diff --git a/02-setup-postgres.sh b/02-setup-postgres.sh new file mode 100755 index 0000000..08cc6e1 --- /dev/null +++ b/02-setup-postgres.sh @@ -0,0 +1,5 @@ +#!/bin/bash +SCRIPTHOME=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPTHOME +sudo docker compose -f postgres/docker-compose.yml up -d +sudo apt -y install libpq-dev diff --git a/10-hosts.sh b/10-hosts.sh new file mode 100755 index 0000000..d4fffac --- /dev/null +++ b/10-hosts.sh @@ -0,0 +1,17 @@ +#!/bin/bash +echo "現在のネットワーク設定はこのようになっています。" +ip a | grep "\(^[[:digit:]]\+\|inet \)" + +echo "example.netのIPアドレスとして何を登録しますか?" +echo "何も入力しなければ 127.0.0.1 を登録します。" +read -p "IPアドレス: " IPADDRESS +if [ -z $IPADDRESS ];then + IPADDRESS="127.0.0.1" +fi + +DOMMEMBER="example\.net git\.example\.net mail\.example\.net smtp\.example\.net" +if [ $(grep -c "$DOMMEMBER" /etc/hosts) -eq 0 ]; then + sudo sed -i "\$a $IPADDRESS\t$DOMMEMBER" /etc/hosts +else + sudo sed -i "s/^[0-9.]\+[[:blank:]]\+\($DOMMEMBER\)/$IPADDRESS\t\1/" /etc/hosts +fi diff --git a/91-teardown.sh b/91-teardown.sh new file mode 100755 index 0000000..d5fdff6 --- /dev/null +++ b/91-teardown.sh @@ -0,0 +1,108 @@ +#!/bin/bash +SCRIPTHOME=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPTHOME + +sudo echo -n "" +if [ $(whoami) = "root" ]; then + echo "sudo せずに実行してください" + exit 0 +fi + +## 認証局の削除 + +# CAの削除 +rm -rf SSL/exampleCA + +if [ $(cat .setupphase.txt) -eq 0 ]; then + exit +fi + +# CA証明書の削除 +sudo rm /usr/local/share/ca-certificates/example.net.ca.crt +sudo update-ca-certificates -f + +if [ $(cat .setupphase.txt) -eq 1 ]; then + exit +fi + +# SSL証明書と秘密鍵の削除 +sudo rm /etc/ssl/private/wildcard.example.net.crt +sudo rm /etc/ssl/private/wildcard.example.net.key + +if [ $(cat .setupphase.txt) -eq 2 ]; then + exit +fi + +# Apacheの削除 +sudo rm /etc/apache2/sites-available/example.net.conf +sudo rm /etc/apache2/sites-available/gitea.conf +sudo rm /etc/apache2/sites-available/kopano.conf +sudo rm /etc/apache2/conf-available/fqdn.conf +sudo apt -y purge apache2 +sudo apt -y autoremove + +if [ $(cat .setupphase.txt) -eq 3 ]; then + exit +fi + +# git接続設定の削除 +rm ~/.ssh/git-key +rm ~/.ssh/git-key.pub +sed -i "/host git\.example\.net/,/~\/\.ssh\/git-key/d" ~/.ssh/config +ssh-keygen -f ~/.ssh/known_hosts -R git.example.net +sudo apt -y purge ssh +sudo apt -y autoremove + +if [ $(cat .setupphase.txt) -eq 4 ]; then + exit +fi + +# ユーザーgitの削除 +sudo deluser --remove-home --force git +sudo rm /usr/local/bin/gitea + +if [ $(cat .setupphase.txt) -eq 5 ]; then + exit +fi + +# コンテナ関連の削除 +sudo docker compose -f docker/docker-compose.yml stop +sudo docker container rm -f kopano gitea rordb +sudo docker container prune -f +sudo docker network rm docker_rornet +sudo docker volume rm -f docker_gitea docker_kopano docker_mysql +sudo docker image rm -f custom/kopano custom/gitea mariadb:10.8.3-jammy +sudo docker image prune -f +sudo docker builder prune -f + +sudo rm docker/config/gitea/conf/app.ini +sudo rm docker/config/gitea/cert/ca.crt +sudo rm docker/config/kopano/packages/cert/server.crt +sudo rm docker/config/kopano/packages/cert/server.key + +if [ $(cat .setupphase.txt) -eq 6 ]; then + exit +fi + +# rvmの削除 +rvm implode +sudo apt -y purge gnupg2 +sudo apt -y autoremove + +tac ~/.bashrc | sed '/# Load RVM/,+4 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.bashrc +tac ~/.bash_profile | sed '/# Load RVM/,+1 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.bash_profile +tac ~/.mkshrc | sed '/\.rvm\/bin/,+2 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.mkshrc +tac ~/.profile | sed '/# Load RVM/,+4 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.profile +tac ~/.zlogin | sed '/# Load RVM/,+1 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.zlogin +tac ~/.zshrc | sed '/\.rvm\/bin/,+2 d' | tac > ~/elifkrow; [ -s ~/elifkrow ] && mv ~/elifkrow ~/.zshrc +[ -f ~/elifkrow ] && rm ~/elifkrow + +if [ $(cat .setupphase.txt) -eq 7 ]; then + exit +fi + +# hostsからのホスト削除 +sudo sed -i "/example\.net git\.example\.net mail\.example\.net smtp\.example\.net/d" /etc/hosts + +# .setupphase.txtの削除 +rm .setupphase.txt diff --git a/92-teardown-postgres.sh b/92-teardown-postgres.sh new file mode 100755 index 0000000..854df2f --- /dev/null +++ b/92-teardown-postgres.sh @@ -0,0 +1,14 @@ +#!/bin/bash +SCRIPTHOME=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPTHOME + +sudo docker compose -f postgres/docker-compose.yml stop +sudo docker container rm -f postgres +sudo docker container prune -f +sudo docker network rm postgres_default +sudo docker volume rm -f postgres_postgres +sudo docker image rm -f postgres +sudo docker image prune -f +sudo docker builder prune -f + +sudo apt -y purge libpq-dev libpq5 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3dd81a0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2023 rohhie@rohhie.net + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE_CA.pl b/LICENSE_CA.pl new file mode 100644 index 0000000..e648552 --- /dev/null +++ b/LICENSE_CA.pl @@ -0,0 +1,6 @@ +# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..7dbf881 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# rorenv +ruby on rails tutorial environment for Ubuntu 22.04 + +## 概要 +Ruby on Rails チュートリアルを学習するための環境を構築する。 + +## 構築方法 + +このリポジトリからソースをダウンロードする。 +``` +git clone https://gitea.rohhie.net/rohhie/rorenv.git +``` + +スクリプトを実行する。 +``` +cd rorenv +./01-setup.sh +``` + +途中で何度か問い合わせがあるが、適切に回答する。 + +## 廃棄方法 + +スクリプトを実行する。 +``` +cd rorenv +./91-teardown.sh +``` + +## その他 + +詳細は、メインサイト参照。 +https://rohhie.net/ruby-on-rails-tutorial-environment/ + +## ライセンス + +MIT + +ただし、CA.plについては、ファイル原本に記載されているものに従う。 diff --git a/SSL/CA.pl b/SSL/CA.pl new file mode 100755 index 0000000..ed1eaed --- /dev/null +++ b/SSL/CA.pl @@ -0,0 +1,243 @@ +#!/usr/bin/perl +# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +# +# Revised 2023-04-23, Rohhie, as follows: +# - When OPENSSL_CONFIG is not specified, the value is obtained from SSLHOME. +# - Get the value to be set to CATOP from SSLHOME. +# - Change the validity period of CA to 30 years. +# - Changed the certificate validity period to 10 years. + +# +# Wrapper around the ca to make it easier to use +# +# WARNING: do not edit! +# Generated by Makefile from ../apps/CA.pl.in + +use strict; +use warnings; + +my $verbose = 1; +my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify"); + +my $openssl = $ENV{'OPENSSL'} // "openssl"; +$ENV{'OPENSSL'} = $openssl; +my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // "-config $ENV{'SSLHOME'}/openssl.cnf"; + +# Command invocations. +my $REQ = "$openssl req $OPENSSL_CONFIG"; +my $CA = "$openssl ca $OPENSSL_CONFIG"; +my $VERIFY = "$openssl verify"; +my $X509 = "$openssl x509"; +my $PKCS12 = "$openssl pkcs12"; + +# Default values for various configuration settings. +my $CATOP = "$ENV{'SSLHOME'}/exampleCA"; +my $CAKEY = "cakey.pem"; +my $CAREQ = "careq.pem"; +my $CACERT = "cacert.pem"; +my $CACRL = "crl.pem"; +my $DAYS = "-days 3650"; # 10 years +my $CADAYS = "-days 10950"; # 30 years +my $NEWKEY = "newkey.pem"; +my $NEWREQ = "newreq.pem"; +my $NEWCERT = "newcert.pem"; +my $NEWP12 = "newcert.p12"; + +# Commandline parsing +my %EXTRA; +my $WHAT = shift @ARGV || ""; +@ARGV = parse_extra(@ARGV); +my $RET = 0; + +# Split out "-extra-CMD value", and return new |@ARGV|. Fill in +# |EXTRA{CMD}| with list of values. +sub parse_extra +{ + foreach ( @OPENSSL_CMDS ) { + $EXTRA{$_} = ''; + } + + my @result; + while ( scalar(@_) > 0 ) { + my $arg = shift; + if ( $arg !~ m/-extra-([a-z0-9]+)/ ) { + push @result, $arg; + next; + } + $arg =~ s/-extra-//; + die("Unknown \"-${arg}-extra\" option, exiting") + unless scalar grep { $arg eq $_ } @OPENSSL_CMDS; + $EXTRA{$arg} .= " " . shift; + } + return @result; +} + + +# See if reason for a CRL entry is valid; exit if not. +sub crl_reason_ok +{ + my $r = shift; + + if ($r eq 'unspecified' || $r eq 'keyCompromise' + || $r eq 'CACompromise' || $r eq 'affiliationChanged' + || $r eq 'superseded' || $r eq 'cessationOfOperation' + || $r eq 'certificateHold' || $r eq 'removeFromCRL') { + return 1; + } + print STDERR "Invalid CRL reason; must be one of:\n"; + print STDERR " unspecified, keyCompromise, CACompromise,\n"; + print STDERR " affiliationChanged, superseded, cessationOfOperation\n"; + print STDERR " certificateHold, removeFromCRL"; + exit 1; +} + +# Copy a PEM-format file; return like exit status (zero means ok) +sub copy_pemfile +{ + my ($infile, $outfile, $bound) = @_; + my $found = 0; + + open IN, $infile || die "Cannot open $infile, $!"; + open OUT, ">$outfile" || die "Cannot write to $outfile, $!"; + while () { + $found = 1 if /^-----BEGIN.*$bound/; + print OUT $_ if $found; + $found = 2, last if /^-----END.*$bound/; + } + close IN; + close OUT; + return $found == 2 ? 0 : 1; +} + +# Wrapper around system; useful for debugging. Returns just the exit status +sub run +{ + my $cmd = shift; + print "====\n$cmd\n" if $verbose; + my $status = system($cmd); + print "==> $status\n====\n" if $verbose; + return $status >> 8; +} + + +if ( $WHAT =~ /^(-\?|-h|-help)$/ ) { + print STDERR <${CATOP}/index.txt"; + close OUT; + open OUT, ">${CATOP}/crlnumber"; + print OUT "01\n"; + close OUT; + # ask user for existing CA certificate + print "CA certificate filename (or enter to create)\n"; + my $FILE; + $FILE = "" unless defined($FILE = ); + $FILE =~ s{\R$}{}; + if ($FILE ne "") { + copy_pemfile($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); + copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); + } else { + print "Making CA certificate ...\n"; + $RET = run("$REQ -new -keyout ${CATOP}/private/$CAKEY" + . " -out ${CATOP}/$CAREQ $EXTRA{req}"); + $RET = run("$CA -create_serial" + . " -out ${CATOP}/$CACERT $CADAYS -batch" + . " -keyfile ${CATOP}/private/$CAKEY -selfsign" + . " -extensions v3_ca" + . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0; + print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0; + } +} elsif ($WHAT eq '-pkcs12' ) { + my $cname = $ARGV[0]; + $cname = "My Certificate" unless defined $cname; + $RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY" + . " -certfile ${CATOP}/$CACERT -out $NEWP12" + . " -export -name \"$cname\" $EXTRA{pkcs12}"); + print "PKCS #12 file is in $NEWP12\n" if $RET == 0; +} elsif ($WHAT eq '-xsign' ) { + $RET = run("$CA -policy policy_anything -infiles $NEWREQ $EXTRA{ca}"); +} elsif ($WHAT eq '-sign' ) { + $RET = run("$CA -policy policy_anything -out $NEWCERT" + . " -infiles $NEWREQ $EXTRA{ca}"); + print "Signed certificate is in $NEWCERT\n" if $RET == 0; +} elsif ($WHAT eq '-signCA' ) { + $RET = run("$CA -policy policy_anything -out $NEWCERT" + . " -extensions v3_ca -infiles $NEWREQ $EXTRA{ca}"); + print "Signed CA certificate is in $NEWCERT\n" if $RET == 0; +} elsif ($WHAT eq '-signcert' ) { + $RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ" + . " -out tmp.pem $EXTRA{x509}"); + $RET = run("$CA -policy policy_anything -out $NEWCERT" + . "-infiles tmp.pem $EXTRA{ca}") if $RET == 0; + print "Signed certificate is in $NEWCERT\n" if $RET == 0; +} elsif ($WHAT eq '-verify' ) { + my @files = @ARGV ? @ARGV : ( $NEWCERT ); + foreach my $file (@files) { + # -CAfile quoted for VMS, since the C RTL downcases all unquoted + # arguments to C programs + my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}"); + $RET = $status if $status != 0; + } +} elsif ($WHAT eq '-crl' ) { + $RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL $EXTRA{ca}"); + print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0; +} elsif ($WHAT eq '-revoke' ) { + my $cname = $ARGV[0]; + if (!defined $cname) { + print "Certificate filename is required; reason optional.\n"; + exit 1; + } + my $reason = $ARGV[1]; + $reason = " -crl_reason $reason" + if defined $reason && crl_reason_ok($reason); + $RET = run("$CA -revoke \"$cname\"" . $reason . $EXTRA{ca}); +} else { + print STDERR "Unknown arg \"$WHAT\"\n"; + print STDERR "Use -help for help.\n"; + exit 1; +} + +exit $RET; diff --git a/SSL/openssl.cnf b/SSL/openssl.cnf new file mode 100644 index 0000000..b3ff3cf --- /dev/null +++ b/SSL/openssl.cnf @@ -0,0 +1,407 @@ +# +# OpenSSL example configuration file. +# See doc/man5/config.pod for more info. +# +# This is mostly being used for generation of certificate requests, +# but may be used for auto loading of providers + +# Note that you can include other files from the main configuration +# file using the .include directive. +#.include filename + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . + + # Use this in order to automatically load providers. +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + +# Extra OBJECT IDENTIFIER info: +# oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +# For FIPS +# Optionally include a file that is generated by the OpenSSL fipsinstall +# application. This file contains configuration data required by the OpenSSL +# fips provider. It contains a named section e.g. [fips_sect] which is +# referenced from the [provider_sect] below. +# Refer to the OpenSSL security policy for more information. +# .include fipsmodule.cnf + +[openssl_init] +providers = provider_sect +ssl_conf = ssl_sect + +# List of providers to load +[provider_sect] +default = default_sect +# The fips section name should match the section name inside the +# included fipsmodule.cnf. +# fips = fips_sect + +# If no providers are activated explicitly, the default one is activated implicitly. +# See man 7 OSSL_PROVIDER-default for more details. +# +# If you add a section explicitly activating any other provider(s), you most +# probably need to explicitly activate the default provider, otherwise it +# becomes unavailable in openssl. As a consequence applications depending on +# OpenSSL may not work correctly which could lead to significant system +# problems including inability to remotely access the system. +[default_sect] +# activate = 1 + + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = $ENV::SSLHOME/exampleCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +unique_subject = no # Set to 'no' to allow creation of + # several certs with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key + +x509_extensions = usr_cert # The extensions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = JA +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Tokyo + +localityName = Locality Name (eg, city) +localityName_default = Chiyoda + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Example Networks Inc. + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_default = example.net +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = webmaster@example.net +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move +subjectAltName=@v3_altname + +# Copy subject details +# issuerAltName=issuer:copy + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName=@v3_altname + +[ v3_altname ] +DNS.1=example.net +DNS.2=*.example.net + + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +basicConstraints = critical,CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) +signer_digest = sha256 # Signing digest to use. (Optional) +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) +ess_cert_id_alg = sha1 # algorithm to compute certificate + # identifier (optional, default: sha1) + +[insta] # CMP using Insta Demo CA +# Message transfer +server = pki.certificate.fi:8700 +# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080 +# tls_use = 0 +path = pkix/ + +# Server authentication +recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer +ignore_keyusage = 1 # potentially needed quirk +unprotected_errors = 1 # potentially needed quirk +extracertsout = insta.extracerts.pem + +# Client authentication +ref = 3078 # user identification +secret = pass:insta # can be used for both client and server side + +# Generic message options +cmd = ir # default operation, can be overridden on cmd line with, e.g., kur + +# Certificate enrollment +subject = "/CN=openssl-cmp-test" +newkey = insta.priv.pem +out_trusted = insta.ca.crt +certout = insta.cert.pem + +[pbm] # Password-based protection for Insta CA +# Server and client authentication +ref = $insta::ref # 3078 +secret = $insta::secret # pass:insta + +[signature] # Signature-based protection for Insta CA +# Server authentication +trusted = insta.ca.crt # does not include keyUsage digitalSignature + +# Client authentication +secret = # disable PBM +key = $insta::newkey # insta.priv.pem +cert = $insta::certout # insta.cert.pem + +[ir] +cmd = ir + +[cr] +cmd = cr + +[kur] +# Certificate update +cmd = kur +oldcert = $insta::certout # insta.cert.pem + +[rr] +# Certificate revocation +cmd = rr +oldcert = $insta::certout # insta.cert.pem + +[ssl_sect] +system_default = system_default_sect + +[system_default_sect] +CipherString = DEFAULT:@SECLEVEL=2 diff --git a/apache/example.net.conf b/apache/example.net.conf new file mode 100644 index 0000000..192bc38 --- /dev/null +++ b/apache/example.net.conf @@ -0,0 +1,27 @@ + + ServerName example.net + + RewriteEngine on + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} + RewriteCond %{SERVER_NAME} =example.net + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] + + + + ServerName example.net + ServerAdmin webmaster@example.net + DocumentRoot /var/www/html + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + ProxyPreserveHost on + ProxyPass / http://localhost:3000/ + ProxyPassReverse / http://localhost:3000/ + RequestHeader set X_FORWARDED_PROTO 'https' + + SSLEngine on + SSLCertificateFile /etc/ssl/private/wildcard.example.net.crt + SSLCertificateKeyFile /etc/ssl/private/wildcard.example.net.key + diff --git a/apache/gitea.conf b/apache/gitea.conf new file mode 100644 index 0000000..4b0df30 --- /dev/null +++ b/apache/gitea.conf @@ -0,0 +1,27 @@ + + ServerName git.example.net + + RewriteEngine on + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} + RewriteCond %{SERVER_NAME} =git.example.net + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] + + + + ServerName git.example.net + ServerAdmin webmaster@example.net + DocumentRoot /var/www/html + + ErrorLog ${APACHE_LOG_DIR}/git-error.log + CustomLog ${APACHE_LOG_DIR}/git-access.log combined + + SSLProxyEngine on + ProxyPreserveHost on + AllowEncodedSlashes NoDecode + ProxyPass / http://localhost:3001/ nocanon + + SSLEngine on + SSLCertificateFile /etc/ssl/private/wildcard.example.net.crt + SSLCertificateKeyFile /etc/ssl/private/wildcard.example.net.key + diff --git a/apache/kopano.conf b/apache/kopano.conf new file mode 100644 index 0000000..9a0f1ef --- /dev/null +++ b/apache/kopano.conf @@ -0,0 +1,30 @@ + + ServerName mail.example.net + + RewriteEngine on + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} + RewriteCond %{SERVER_NAME} =mail.example.net + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] + + + + ServerName mail.example.net + ServerAdmin webmaster@example.net + DocumentRoot /var/www/html + + ErrorLog ${APACHE_LOG_DIR}/kopano-error.log + CustomLog ${APACHE_LOG_DIR}/kopano-access.log combined + + RewriteEngine on + RewriteCond %{REQUEST_URI} ^/$ + RewriteRule ^/(.*)$ /webapp [R=301,L] + + ProxyPreserveHost on + ProxyPass / http://localhost:8080/ + ProxyPassReverse / http://localhost:8080/ + + SSLEngine on + SSLCertificateFile /etc/ssl/private/wildcard.example.net.crt + SSLCertificateKeyFile /etc/ssl/private/wildcard.example.net.key + diff --git a/docker/config/gitea/Dockerfile b/docker/config/gitea/Dockerfile new file mode 100644 index 0000000..a299be2 --- /dev/null +++ b/docker/config/gitea/Dockerfile @@ -0,0 +1,4 @@ +FROM gitea/gitea +USER root +COPY ./cert /usr/local/share/ca-certificates/ +RUN update-ca-certificates diff --git a/docker/config/kopano/Dockerfile b/docker/config/kopano/Dockerfile new file mode 100644 index 0000000..eaf29e5 --- /dev/null +++ b/docker/config/kopano/Dockerfile @@ -0,0 +1,50 @@ +FROM ubuntu:focal +USER root +ADD entrypoint.sh / +ENTRYPOINT ["/entrypoint.sh"] +COPY ./packages /root/packages +ENV DEBIAN_FRONTEND=noninteractive \ + SERVER_MYSQL_HOST=kopano_db \ + SERVER_MYSQL_PORT=3306 \ + SERVER_MYSQL_USER=kopano \ + SERVER_MYSQL_PASSWORD=kopano \ + SERVER_MYSQL_DATABASE=kopano \ + LANG=en_US.UTF-8 \ + LANGUAGE=en_US:en \ + LC_ALL=en_US.UTF-8 +RUN cd /root/packages && \ + apt update && \ + apt install -y \ + apache2 \ + curl \ + gnupg \ + mariadb-client \ + iproute2 \ + php \ + postfix \ + postfix-mysql \ + sasl2-bin \ + software-properties-common \ + vim && \ + mkdir -p /var/spool/postfix/var/run && \ + cp -ar /var/run/saslauthd /var/spool/postfix/var/run/ && \ + tar -zxvf core-11.0.2.51.c08b7f4-Ubuntu_20.04-amd64.tar.gz && \ + rm core-11.0.2.51.c08b7f4-Ubuntu_20.04-amd64.tar.gz && \ + tar -zxvf webapp-6.0.0.66.43d5c5d-Ubuntu_20.04-all.tar.gz && \ + rm webapp-6.0.0.66.43d5c5d-Ubuntu_20.04-all.tar.gz && \ + dpkg -i core-11.0.2.51.c08b7f4-Ubuntu_20.04-amd64/* || true && \ + dpkg -i webapp-6.0.0.66.43d5c5d-Ubuntu_20.04-all/* || true && \ + apt -y --fix-broken install && \ + curl https://download.kopano.io/zhub/z-push:/final/Ubuntu_20.04/Release.key -o zhub.key && \ + apt-key add zhub.key && \ + rm zhub.key && \ + add-apt-repository "deb https://download.kopano.io/zhub/z-push:/final/Ubuntu_20.04/ /" && \ + apt install -y z-push-backend-kopano z-push-ipc-sharedmemory z-push-config-apache && \ + chown www-data:www-data /var/lib/z-push/ /var/log/z-push/ && \ + a2dissite 000-default && \ + a2ensite kopano-webapp && \ + a2enmod expires headers && \ + mkdir -p /var/lib/kopano/attachments && \ + chown 999:999 /var/lib/kopano/attachments && \ + chmod 750 /var/lib/kopano/attachments && \ + locale-gen en_US.UTF-8 diff --git a/docker/config/kopano/entrypoint.sh b/docker/config/kopano/entrypoint.sh new file mode 100755 index 0000000..08761b2 --- /dev/null +++ b/docker/config/kopano/entrypoint.sh @@ -0,0 +1,64 @@ +#!/bin/bash +set -e + +echo "Start Kopano container with paramater : $@" + +trap sig_term SIGTERM + +sig_term() { + echo "CATCH SIGTERM" + pkill -SIGTERM kopano-server + pkill -SIGTERM kopano-dagent + pkill -SIGTERM kopano-gateway + pkill -SIGTERM kopano-ical + pkill -SIGTERM kopano-monitor + pkill -SIGTERM kopano-search + pkill -SIGTERM kopano-spooler + pkill -SIGTERM kopano-statsd + /etc/init.d/saslauthd stop + /usr/sbin/postfix stop + /usr/sbin/apachectl stop + wait + exit 0 +} + +# Make configuration. +/root/packages/config.sh + +# Wait for service to start. +while + mysqladmin -h $SERVER_MYSQL_HOST -u $SERVER_MYSQL_USER status -p$SERVER_MYSQL_PASSWORD + [ $? -ne 0 ] +do + sleep 5 +done + +# Start services. +/usr/sbin/apachectl start +/usr/sbin/postfix start +/etc/init.d/saslauthd start +/usr/sbin/kopano-server & +/usr/sbin/kopano-dagent -l & +/usr/sbin/kopano-gateway & +/usr/sbin/kopano-ical & +/usr/sbin/kopano-monitor & +/usr/sbin/kopano-search & +/usr/sbin/kopano-spooler & +/usr/lib/x86_64-linux-gnu/kopano/kopano-statsd & + +while /etc/init.d/saslauthd status + [ $? -ne 0 ] +do + sleep 3 +done +saslauthd -a rimap -O 127.0.0.1 -c + +# Execute parameter. +exec "$@" + +# Add first user. +/root/packages/addfirstuser.sh + + +# Infinite loop. +while : ; do sleep 1 ; done diff --git a/docker/config/kopano/packages/addfirstuser.sh b/docker/config/kopano/packages/addfirstuser.sh new file mode 100755 index 0000000..a7a002e --- /dev/null +++ b/docker/config/kopano/packages/addfirstuser.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +echo "addfirstuser.sh: Add first user" +if [ -f /root/packages/useradded ]; then + echo "addfirstuser.sh: The first user has already been added" + exit 0 +fi + +# +# Add first user. +# +kopano-admin -c $KOPANOADMUSER -p $KOPANOADMPASS -e $KOPANOADMUSER@$MYDOMAIN -f $KOPANOADMUSER -a yes + +# +# Configuration complete. +# +touch /root/packages/useradded +echo "addfirstuser.sh: The first user has been added" diff --git a/docker/config/kopano/packages/config.sh b/docker/config/kopano/packages/config.sh new file mode 100755 index 0000000..a0c8839 --- /dev/null +++ b/docker/config/kopano/packages/config.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +echo "config.sh: Start configuration" +if [ -f /root/packages/configured ]; then + echo "config.sh: It was already configured" + exit 0 +fi + +# +# Postfix +# + +# basic settings. +postconf -e maillog_file=/var/log/postfix.log +postconf -e myhostname=kopano +postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-aliases.cf +postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-groups.cf +postconf -e virtual_transport=lmtp:127.0.0.1:2003 +postconf -e virtual_mailbox_domains=$MYDOMAIN + +# get aliases from database. +cat < /etc/postfix/mysql-aliases.cf +user = $SERVER_MYSQL_USER +password = $SERVER_MYSQL_PASSWORD +hosts = $SERVER_MYSQL_HOST +dbname = $SERVER_MYSQL_DATABASE +query = select value from objectproperty where objectid=(select objectid from objectproperty where value='%s' limit 1) and propname='loginname'; +EOF +chmod 600 /etc/postfix/mysql-aliases.cf + +cat < /etc/postfix/mysql-groups.cf +user = $SERVER_MYSQL_USER +password = $SERVER_MYSQL_PASSWORD +hosts = $SERVER_MYSQL_HOST +dbname = $SERVER_MYSQL_DATABASE +query = select value from objectproperty where objectid in ( select objectid from objectrelation where parentobjectid in ( select objectid from objectproperty where value='%s' and propname='emailaddress' ) and relationtype=1 ) and propname='emailaddress'; +EOF +chmod 600 /etc/postfix/mysql-groups.cf + +# enable sasl authentication. +sed -i "s/^START=no/START=yes/" /etc/default/saslauthd +sed -i 's/^MECHANISMS="pam"/MECHANISMS="rimap"/' /etc/default/saslauthd +sed -i 's/^MECH_OPTIONS=""/MECH_OPTIONS="127.0.0.1"/' /etc/default/saslauthd +sed -i "s/^THREADS=5/THREADS=0/" /etc/default/saslauthd +sed -i 's@^OPTIONS="-c -m /var/run/saslauthd"@OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"@' /etc/default/saslauthd +adduser postfix sasl +cat < /etc/postfix/sasl/smtpd.conf +pwcheck_method: saslauthd +mech_list: plain login +EOF +postconf -e "mua_client_restrictions=permit_sasl_authenticated reject" +sed -i "17,21 s/^#//g" /etc/postfix/master.cf +sed -i "23 s/^#//g" /etc/postfix/master.cf +sed -i "29,32 s/^#//g" /etc/postfix/master.cf +sed -i "34 s/^#//g" /etc/postfix/master.cf + +# disable chroot for all acrive service. +sed -i "s/^\([a-z]\+ \+[a-z\-]\+ \+[a-z\-]\+ \+[a-z\-]\+ \+\)y\( \+.\+$\)/\1n\2/g" /etc/postfix/master.cf + +# +# kopano-server +# +if [ -v SERVER_MYSQL_HOST ]; then sed -i "s/^#mysql_host = localhost\$/mysql_host = $SERVER_MYSQL_HOST/" /etc/kopano/server.cfg; fi +if [ -v SERVER_MYSQL_PORT ]; then sed -i "s/^#mysql_port = 3306\$/mysql_port = $SERVER_MYSQL_PORT/" /etc/kopano/server.cfg; fi +if [ -v SERVER_MYSQL_USER ]; then sed -i "s/^#mysql_user = root\$/mysql_user = $SERVER_MYSQL_USER/" /etc/kopano/server.cfg; fi +if [ -v SERVER_MYSQL_PASSWORD ]; then sed -i "s/^#mysql_password =\$/mysql_password = $SERVER_MYSQL_PASSWORD/" /etc/kopano/server.cfg; fi +if [ -v SERVER_MYSQL_DATABASE ]; then sed -i "s/^#mysql_database = kopano\$/mysql_database = $SERVER_MYSQL_DATABASE/" /etc/kopano/server.cfg; fi +sed -i "s/^#disabled_features = imap pop3/disabled_features = pop3/" /etc/kopano/server.cfg + +# +# kopano-gateway +# +sed -i "s/^#imap_listen = \*%lo:143/imap_listen = 0.0.0.0:143/" /etc/kopano/gateway.cfg + +# +# kopano-ical +# +sed -i "s@^#server_timezone = .\+\$@server_timezone = $TZ@" /etc/kopano/ical.cfg + +# +# WebApp +# +sed -i 's/"SECURE_COOKIES", true/"SECURE_COOKIES", false/' /etc/kopano/webapp/config.php + +# +# Z-Push +# +sed -i "s@define('TIMEZONE', '');@define('TIMEZONE', '$TZ');@" /etc/z-push/z-push.conf.php + +# +# Register certificates. +# +cp -a /root/packages/cert/server.crt /etc/ssl/certs/ && \ + postconf -e smtpd_tls_cert_file=/etc/ssl/certs/server.crt +cp -a /root/packages/cert/server.key /etc/ssl/private/ && \ + postconf -e smtpd_tls_key_file=/etc/ssl/private/server.key + +# +# Add first user. +# +kopano-admin -c $KOPANOADMUSER -p $KOPANOADMPASS -e $KOPANOADMUSER@$MYDOMAIN -f $KOPANOADMUSER -a yes + +# +# Configuration complete. +# +touch /root/packages/configured +echo "config.sh: Configuration complete" diff --git a/docker/config/mariadb-init/init.sql b/docker/config/mariadb-init/init.sql new file mode 100644 index 0000000..0b82560 --- /dev/null +++ b/docker/config/mariadb-init/init.sql @@ -0,0 +1,4 @@ +CREATE DATABASE IF NOT EXISTS `kopano`; +CREATE DATABASE IF NOT EXISTS `gitea`; +GRANT ALL PRIVILEGES ON kopano.* TO 'rordb'@'%'; +GRANT ALL PRIVILEGES ON gitea.* TO 'rordb'@'%'; diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..13e7601 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,84 @@ +version: "3.9" + +networks: + rornet: + ipam: + config: + - subnet: "172.25.0.0/16" + gateway: "172.25.0.1" + +volumes: + kopano: + gitea: + mysql: + +services: + kopano: + build: ./config/kopano + image: custom/kopano + container_name: kopano + restart: unless-stopped + volumes: + - kopano:/var/lib/kopano/attachments + networks: + - rornet + hostname: smtp.example.net + environment: + - TZ=Asia/Tokyo + - MYDOMAIN=example.net + - KOPANOADMUSER=webmaster + - KOPANOADMPASS=webmaster + - SERVER_MYSQL_HOST=db + - SERVER_MYSQL_USER=rordb + - SERVER_MYSQL_PASSWORD=rordb + ports: + - 8080:80 + - 25:25 + - 143:143 + - 465:465 + - 587:587 + depends_on: + - db + + gitea: + build: ./config/gitea + image: custom/gitea + container_name: gitea + environment: + - USER_UID=1001 + - USER_GID=1001 + - GITEA__database__DB_TYPE=mysql + - GITEA__database__HOST=db:3306 + - GITEA__database__NAME=gitea + - GITEA__database__USER=rordb + - GITEA__database__PASSWD=rordb + restart: unless-stopped + networks: + - rornet + volumes: + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + - /home/git/.ssh:/data/git/.ssh + - ./config/gitea/conf:/data/gitea/conf + ports: + - 3001:3000 + - 127.0.0.1:2222:22 + depends_on: + - db + + db: + image: mariadb:10.8.3-jammy + container_name: rordb + restart: unless-stopped + command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW + volumes: + - mysql:/var/lib/mysql + - ./config/mariadb-init:/docker-entrypoint-initdb.d + networks: + - rornet + environment: + - TZ=Asia/Tokyo + - MYSQL_ROOT_PASSWORD=rordb + - MYSQL_USER=rordb #config/mariadb-init/init.sqlも一緒に変更 + - MYSQL_PASSWORD=rordb diff --git a/postgres/docker-compose.yml b/postgres/docker-compose.yml new file mode 100644 index 0000000..f8f94ab --- /dev/null +++ b/postgres/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.1' + +volumes: + postgres: + +services: + postgres: + image: postgres + container_name: postgres + restart: always + environment: + POSTGRES_DB: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgresql + volumes: + - postgres:/var/lib/postgresql/data + ports: + - 5432:5432