Skip to content

Commit

Permalink
Run nginx as docker container instead of on the host system (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
hakwerk committed Apr 2, 2022
1 parent 8f97390 commit 954d9bb
Show file tree
Hide file tree
Showing 56 changed files with 117 additions and 91 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ The end users in your organization / lab can visit the public pages of you LabCA
## Troubleshooting

After installing sometimes the application is not starting up properly and it can be quite hard to figure out why. Some log files to check in case of issues are:
* /etc/nginx/ssl/acme_tiny.log
* /home/labca/nginx_data/ssl/acme_tiny.log
* /home/labca/logs/commander.log
* cd /home/labca/boulder; docker-compose logs labca
* cd /home/labca/boulder; docker-compose logs boulder
Expand All @@ -106,7 +106,7 @@ After installing sometimes the application is not starting up properly and it ca

### Common error messages

If you get "**No valid IP addresses found for <hostname>**" in /etc/nginx/ssl/acme_tiny.log, solve it by entering the hostname in your local DNS. Same for "**Could not resolve host: <hostname>**" in /var/log/labca.err.
If you get "**No valid IP addresses found for <hostname>**" in /home/labca/nginx_data/ssl/acme_tiny.log, solve it by entering the hostname in your local DNS. Same for "**Could not resolve host: <hostname>**" in /var/log/labca.err.

When issuing a certificate, LabCA/boulder checks for CAA (Certification Authority Authorization) records in DNS, which specify what CAs are allowed to issue certificates for the domain. If you get an error like "**SERVFAIL looking up CAA for internal**" or "**CAA record for ca01.foo.internal prevents issuance**", you can try to add something like this to your DNS domain:
```
Expand Down
2 changes: 1 addition & 1 deletion acme_tiny.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def main(argv=None):
## openssl genrsa 4096 > account.key
## openssl genrsa 4096 > domain.key
## openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:tessie.hakwerk.local")) > domain.csr
## python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/html/.well-known/acme-challenge/ > domain_chain.crt
## python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /home/labca/nginx_data/static/.well-known/acme-challenge/ > domain_chain.crt
## cp domain_chain.crt ~/boulder/test/

## docker exec -ti boulder_boulder_1 /bin/bash
Expand Down
2 changes: 1 addition & 1 deletion backup
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mkdir -p /home/labca/backup
cd /home/labca/boulder
docker-compose exec -T bmysql mysqldump boulder_sa_integration >$TMPDIR/boulder_sa_integration.sql

cp -p /etc/nginx/ssl/*key* /etc/nginx/ssl/*cert.pem /etc/nginx/ssl/*.csr $TMPDIR/
cp -p /home/labca/nginx_data/ssl/*key* /home/labca/nginx_data/ssl/*cert.pem /home/labca/nginx_data/ssl/*.csr $TMPDIR/

cp -rp /home/labca/admin/data $TMPDIR/

Expand Down
22 changes: 10 additions & 12 deletions commander
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function wait_server() {
read txt
case $txt in
"trust-store")
cp /etc/nginx/ssl/labca_cert.pem /usr/local/share/ca-certificates/labca_cert.crt
cp /home/labca/nginx_data/ssl/labca_cert.pem /usr/local/share/ca-certificates/labca_cert.crt
cp ~labca/admin/data/root-ca.pem /usr/local/share/ca-certificates/root-ca.crt
update-ca-certificates &>>$LOGFILE
echo "Waiting for initial startup of the docker containers..." &>>$LOGFILE
Expand All @@ -58,12 +58,11 @@ case $txt in
wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE
;;
"acme-request")
cd /etc/nginx/ssl
cd /home/labca/nginx_data/ssl
[ -e account.key ] || openssl genrsa 4096 > account.key
[ -e labca_key.pem ] || openssl genrsa 4096 > labca_key.pem
san=$(openssl x509 -noout -text -in labca_cert.pem | grep DNS:)
openssl req -new -sha256 -key labca_key.pem -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=$san")) > domain.csr
chown -R www-data:www-data *
url=$(grep 'DEFAULT_DIRECTORY_URL =' /home/labca/acme_tiny.py | sed -e 's/.*=[ ]*//' | sed -e 's/\"//g')
wait_server $url
sleep 10
Expand All @@ -72,16 +71,18 @@ case $txt in
ln -sf /home/labca/labca/logrotate_d /etc/logrotate.d/labca
;;
"nginx-remove-redirect")
perl -i -p0e 's/\n # BEGIN temporary redirect\n location = \/ \{\n return 302 \/admin\/;\n }\n # END temporary redirect\n//igs' /etc/nginx/sites-available/labca
perl -i -p0e 's/\n # BEGIN temporary redirect\n location = \/ \{\n return 302 \/admin\/;\n }\n # END temporary redirect\n//igs' /home/labca/nginx_data/conf.d/labca.conf
;;
"nginx-reload")
service nginx reload
cd /home/labca/boulder
docker-compose exec -T nginx nginx -s reload &>>$LOGFILE
;;
"nginx-restart")
service nginx restart
cd /home/labca/boulder
docker-compose restart nginx &>>$LOGFILE
;;
"log-cert")
[ -f /etc/nginx/ssl/acme_tiny.log ] && tail -200 /etc/nginx/ssl/acme_tiny.log || /bin/true
[ -f /home/labca/nginx_data/ssl/acme_tiny.log ] && tail -200 /home/labca/nginx_data/ssl/acme_tiny.log || /bin/true
exit 0
;;
"log-commander")
Expand Down Expand Up @@ -120,11 +121,8 @@ case $txt in
exit 0
;;
"log-web")
tail -f -n 50 /var/log/nginx/access.log
;;
"log-weberr")
[ -f /var/log/nginx/error.log ] && tail -200 /var/log/nginx/error.log || /bin/true
exit 0
cd /home/labca/boulder
docker-compose logs -f --no-color --tail=50 nginx
;;
"log-components")
timezone=$(cat /etc/timezone)
Expand Down
2 changes: 0 additions & 2 deletions gui/apply
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ cp $PKI_ROOT_CERT_BASE.der certs/
cp $PKI_INT_CERT_BASE.pem certs/
cp $PKI_INT_CERT_BASE.der certs/

chown -R www-data:www-data .


cd /boulder/labca
$PKI_PWD/apply-boulder
2 changes: 0 additions & 2 deletions gui/apply-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,3 @@ sed -i -e "s|\[PKI_ROOT_FINGERPRINT\]|$PKI_ROOT_FINGERPRINT|g" cps/index.html
sed -i -e "s|\[PKI_ROOT_VALIDITY\]|$PKI_ROOT_VALIDITY|g" cps/index.html

sed -i -e "s|\[PKI_COMPANY_NAME\]|$PKI_DEFAULT_O|g" terms/v1.html

chown -R www-data:www-data .
35 changes: 11 additions & 24 deletions gui/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func errorHandler(w http.ResponseWriter, r *http.Request, err error, status int)
var FileErrors []interface{}
data := getLog(w, r, "cert")
if data != "" {
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "/etc/nginx/ssl/acme_tiny.log", "Content": data})
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "/home/labca/nginx_data/ssl/acme_tiny.log", "Content": data})
}
data = getLog(w, r, "commander")
if data != "" {
Expand Down Expand Up @@ -1006,7 +1006,7 @@ func _manageGet(w http.ResponseWriter, r *http.Request) {
components := _parseComponents(getLog(w, r, "components"))
for i := 0; i < len(components); i++ {
if components[i].Name == "NGINX Webserver" {
components[i].LogURL = r.Header.Get("X-Request-Base") + "/logs/weberr"
components[i].LogURL = r.Header.Get("X-Request-Base") + "/logs/web"
components[i].LogTitle = "Web Error Log"

btn := make(map[string]interface{})
Expand Down Expand Up @@ -1185,11 +1185,6 @@ func logsHandler(w http.ResponseWriter, r *http.Request) {
case "web":
name = "Web Access Log"
message = "Live view on the NGINX web server access log."
case "weberr":
name = "Web Error Log"
message = "Log file for the NGINX web server error log."
wsurl = ""
data = getLog(w, r, logType)
default:
errorHandler(w, r, fmt.Errorf("unknown log type '%s'", logType), http.StatusBadRequest)
return
Expand Down Expand Up @@ -2272,21 +2267,13 @@ func activeNav(active string, uri string, requestBase string) []navItem {
},
}
web := navItem{
Name: "Web Access",
Name: "Web Server",
Icon: "fa-globe",
Attrs: map[template.HTMLAttr]string{
"href": requestBase + "/logs/web",
"title": "Live view on the NGINX web server access log",
},
}
weberr := navItem{
Name: "Web Error",
Icon: "fa-times",
Attrs: map[template.HTMLAttr]string{
"href": requestBase + "/logs/weberr",
"title": "Log file for the NGINX web server error log",
},
}
logs := navItem{
Name: "Logs",
Icon: "fa-files-o",
Expand All @@ -2295,7 +2282,7 @@ func activeNav(active string, uri string, requestBase string) []navItem {
"title": "Log Files",
},
IsActive: strings.HasPrefix(uri, "/logs/"),
SubMenu: []navItem{cert, boulder, audit, labca, web, weberr},
SubMenu: []navItem{cert, boulder, audit, labca, web},
}
manage := navItem{
Name: "Manage",
Expand Down Expand Up @@ -2491,13 +2478,13 @@ func main() {

r.NotFoundHandler = http.HandlerFunc(notFoundHandler)
if isDev {
r.PathPrefix("/accounts/static/").Handler(http.StripPrefix("/accounts/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/authz/static/").Handler(http.StripPrefix("/authz/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/challenges/static/").Handler(http.StripPrefix("/challenges/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/certificates/static/").Handler(http.StripPrefix("/certificates/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/orders/static/").Handler(http.StripPrefix("/orders/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/logs/static/").Handler(http.StripPrefix("/logs/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("../www"))))
r.PathPrefix("/accounts/static/").Handler(http.StripPrefix("/accounts/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/authz/static/").Handler(http.StripPrefix("/authz/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/challenges/static/").Handler(http.StripPrefix("/challenges/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/certificates/static/").Handler(http.StripPrefix("/certificates/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/orders/static/").Handler(http.StripPrefix("/orders/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/logs/static/").Handler(http.StripPrefix("/logs/static/", http.FileServer(http.Dir("../static"))))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("../static"))))
}
r.Use(authorized)

Expand Down
60 changes: 37 additions & 23 deletions install
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ clone_or_pull() {
# Checkout the latest release tag
checkout_release() {
local branch="$1"
if [ "$branch" == "" ] || [ "$branch" == "master" ]; then
if [ "$branch" == "" ] || [ "$branch" == "master" ] || [ "$branch" == "main" ]; then
cd "$cloneDir"
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
sudo -u labca -H git reset --hard $TAG &>>$installLog
Expand Down Expand Up @@ -393,7 +393,7 @@ install_pkg() {
}

install_extra() {
local packages=(apt-transport-https ca-certificates curl gnupg2 net-tools nginx software-properties-common tzdata ucspi-tcp zip python)
local packages=(apt-transport-https ca-certificates curl gnupg2 net-tools software-properties-common tzdata ucspi-tcp zip python)
for package in "${packages[@]}"; do
install_pkg "$package"
done
Expand Down Expand Up @@ -425,11 +425,22 @@ static_web() {

local msg="Static web pages"
msg_info "$msg"
[ -e /etc/nginx/sites-available/labca ] || cp $cloneDir/nginx.conf /etc/nginx/sites-available/labca
[ -e /etc/nginx/sites-enabled/labca ] || ln -s ../sites-available/labca /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
if [ -d /etc/nginx ]; then
# Migrate cert from host nginx to dockerized nginx
[ -d /home/labca/nginx_data/ssl ] || mkdir -p /home/labca/nginx_data/ssl
mv /etc/nginx/ssl/* /home/labca/nginx_data/ssl/
mv /etc/nginx /etc/nginx.backup
fi

[ -d /home/labca/nginx_data/conf.d ] || mkdir -p /home/labca/nginx_data/conf.d
[ -d /home/labca/nginx_data/ssl ] || mkdir -p /home/labca/nginx_data/ssl
cp $cloneDir/nginx.conf /home/labca/nginx_data/conf.d/labca.conf
if [ -f "$boulderLabCADir/setup_complete" ]; then
perl -i -p0e 's/\n # BEGIN temporary redirect\n location = \/ \{\n return 302 \/admin\/;\n }\n # END temporary redirect\n//igs' /home/labca/nginx_data/conf.d/labca.conf
fi

cd /var/www/html
[ -d /home/labca/nginx_data/static ] || mkdir /home/labca/nginx_data/static
cd /home/labca/nginx_data/static
git status --short &> /dev/null || rc=$?
if [ $rc -gt 0 ]; then
git init >>$installLog
Expand All @@ -438,9 +449,10 @@ static_web() {
git commit --all --quiet -m "LabCA before update $runId" &>>$installLog && { msg_ok "Commit existing modifications of $adminDir"; msg_info "$msg"; } || true

mkdir -p .well-known/acme-challenge
find .well-known/acme-challenge/ -mtime +10 -exec rm {} \; # Clean up files older than 10 days
mkdir -p crl
[ -e cert ] || ln -s certs cert
cp -rp $cloneDir/www/* .
cp -rp $cloneDir/static/* .
sed -i -e "s|\[LABCA_CPS_LOCATION\]|http://$LABCA_FQDN/cps/|g" cps/index.html
sed -i -e "s|\[LABCA_CERTS_LOCATION\]|http://$LABCA_FQDN/certs/|g" cps/index.html

Expand All @@ -451,8 +463,6 @@ static_web() {
export PKI_DEFAULT_O=$(grep organization $adminDir/data/config.json | sed -e 's/.*:[ ]*//' | sed -e 's/\",//g' | sed -e 's/\"//g')

$adminDir/apply-nginx
else
chown -R www-data:www-data .
fi

git add --all &>/dev/null || true
Expand All @@ -463,19 +473,16 @@ static_web() {

# Create a temporary self-signed certificate if there is no certificate yet
selfsigned_cert() {
if [ -e /etc/nginx/ssl/labca_cert.pem ]; then
if [ -e /home/labca/nginx_data/ssl/labca_cert.pem ]; then
msg_ok "Certificate is present"
else
local msg="Create self-signed certificate"
msg_info "$msg"
mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl
mkdir -p /home/labca/nginx_data/ssl
cd /home/labca/nginx_data/ssl
openssl req -x509 -nodes -sha256 -newkey rsa:2048 -keyout labca_key.pem -out labca_cert.pem -days 7 \
-subj "/O=LabCA/CN=$LABCA_FQDN" -reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nbasicConstraints=CA:FALSE\nnsCertType=server\nsubjectAltName=DNS:$LABCA_FQDN")) &>>$installLog
chown -R www-data:www-data labca_*

service nginx restart &>>$installLog
msg_ok "$msg"
fi
}
Expand Down Expand Up @@ -720,13 +727,15 @@ cleanup() {
local msg="Cleaning up obsolete files"
msg_info "$msg"

rm -f /var/www/html/css/skeleton.css
rm -f /var/www/html/css/skeleton-tabs.css
rm -f /var/www/html/css/normalize.css
rm -f /var/www/html/css/font.css
rm -f /var/www/html/img/favicon.ico
rm -f /var/www/html/js/jquery-3.3.1.min.js
rm -f /var/www/html/js/skeleton-tabs.js
if [ -d /var/www/html ]; then
rm -f /var/www/html/css/skeleton.css
rm -f /var/www/html/css/skeleton-tabs.css
rm -f /var/www/html/css/normalize.css
rm -f /var/www/html/css/font.css
rm -f /var/www/html/img/favicon.ico
rm -f /var/www/html/js/jquery-3.3.1.min.js
rm -f /var/www/html/js/skeleton-tabs.js
fi
rm -f $adminDir/templates/cert.tmpl
rm -f $adminDir/templates/error.tmpl
rm -f $adminDir/templates/final.tmpl
Expand All @@ -739,6 +748,11 @@ cleanup() {
rm -f $adminDir/templates/setup.tmpl
rm -f $adminDir/templates/wrapup.tmpl

# Remove host nginx if installed, as we are now using the docker container
systemctl stop nginx &>>$installLog || true
systemctl disable nginx &>>$installLog || true
apt remove -y nginx &>>$installLog

msg_ok "$msg"
}

Expand Down Expand Up @@ -784,7 +798,7 @@ startup() {

# If the nginx certificate is self-signed then show extra text
first_time() {
local certFile="/etc/nginx/ssl/labca_cert.pem"
local certFile="/home/labca/nginx_data/ssl/labca_cert.pem"
[ -e "$certFile" ] || msg_fatal "The SSL certificate $certFile does not exist"

local subject=$(openssl x509 -noout -in "$certFile" -subject_hash)
Expand Down
2 changes: 1 addition & 1 deletion logrotate_d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/etc/nginx/ssl/*.log
/home/labca/nginx_data/ssl/*.log
/home/labca/logs/cron-*.log
{
rotate 4
Expand Down
Loading

0 comments on commit 954d9bb

Please sign in to comment.