Caddy (no jail)

ee_mart

Cadet
Joined
Feb 12, 2022
Messages
3
* Get download link from https://caddyserver.com/download
Code:
mkdir -p /mnt/nas/adm/caddy
wget -O /mnt/nas/adm/caddy/caddy "https://caddyserver.com/api/download?os=freebsd&arch=amd64&idempotency=52747663821567"
chmod +x /mnt/nas/adm/caddy/caddy


* If you want Caddy to serve on 80/443 port, have multiple IP-s and bind TrueNAS GUI to different one (System->General).
/mnt/nas/adm/caddy/Caddyfile
Code:
http:// {
        bind 192.168.1.1
        respond Hello
}


/mnt/nas/adm/caddy/env
Code:
XDG_DATA_HOME=/mnt/nas/adm/caddy/data
XDG_CONFIG_HOME=/mnt/nas/adm/caddy/config


/mnt/nas/adm/caddy/start.sh
Code:
#!/bin/sh
env=/mnt/nas/adm/caddy/env
bin=/mnt/nas/adm/caddy/caddy
log=/mnt/nas/adm/caddy/caddy.log
pid=/mnt/nas/adm/caddy/caddy.pid
con=/mnt/nas/adm/caddy/Caddyfile

caddy_start(){
sysctl -w kern.ipc.maxsockbuf=3014656
${bin} start --config ${con} --envfile ${env} --pidfile ${pid} >> ${log} 2>&1
 if [ $? -eq 0 ] && ps -ax -o pid | grep -q "$(cat ${pid})"; then
  echo "Caddy started"
  echo "Log: ${log}"
   else
    echo "Error: Caddy failed to start"
    echo "Check the caddy log: ${log}"
 fi
}

if [ -z $(pgrep caddy) ] && [ ! -f ${pid} ]; then 
 caddy_start
fi

if [ -z $(pgrep caddy) ] && [ -f ${pid} ]; then
 rm ${pid}
 caddy_start
fi

if [ -n $(pgrep caddy) ] && [ ! -f ${pid} ]; then 
 kill -9 $(pgrep caddy)
 caddy_start
fi

if [ -n $(pgrep caddy) ] && [ -f ${pid} ] && [ $(pgrep caddy) -ne $(cat ${pid}) ]; then
 rm ${pid}
 kill -9 $(pgrep caddy)
 caddy_start
fi


/mnt/nas/adm/caddy/upgrade.sh
Code:
#!/bin/sh
/mnt/nas/adm/caddy/caddy upgrade
/mnt/nas/adm/caddy/caddy stop
/mnt/nas/adm/caddy/start.sh


make scripts executable
Code:
chmod +x /mnt/nas/adm/caddy/start.sh
chmod +x /mnt/nas/adm/caddy/upgrade.sh


start Caddy when system starts
Tasks->Init/Shutdown Scripts->Add
Description: Caddy start
Type: Script: /mnt/nas/adm/caddy/start.sh
When: Post init

check Caddy periodically
Tasks->Cron Jobs
Description: Caddy
Command: /mnt/nas/adm/caddy/start.sh
Run As User: root
Schedule: Daily

upgrade Caddy periodically
Tasks->Cron Jobs
Description: Caddy upgrade
Command: /mnt/nas/adm/caddy/upgrade.sh
Run As User: root
Schedule: Monthly
 

Samuel Tai

Never underestimate your own stupidity
Moderator
Joined
Apr 24, 2020
Messages
5,399
Although interesting, this setup isn’t recommended, as it conflicts with TrueNAS’s web ports and likely won’t survive system upgrades. Running Caddy in a jail is still recommended.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
as it conflicts with TrueNAS’s web ports and likely won’t survive system upgrades.
While I wonder about the purpose of this, neither of these is (necessarily) true. TrueNAS can be set to use whatever ports are desired, and so can Caddy; there's no reason they'd need to conflict. And nothing in this guide would be affected by a system upgrade; all the scripts (and the binary itself) are stored on the data pool, and the scripts to run them are configured through the GUI and thus would also survive upgrades. The only issue would be if a subsequent upgrade required a different ABI, but given that Caddy's written in Go, that doesn't seem likely.
 

ee_mart

Cadet
Joined
Feb 12, 2022
Messages
3
My experience is that TrueNAS Core GUI binds to port 80 no matter what. Just use different IP for GUI and Caddy (notice bind directive in Caddyfile).

Motivation was to serve Caddy and other system built-in services from the same IP.
* I'm aware that it could be resolved outside TrueNAS
* I'm aware that it's theoretically less secure
* I wasn't able to change kern.ipc.maxsockbuf in jail [1]

[1] - https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size
 

ee_mart

Cadet
Joined
Feb 12, 2022
Messages
3
* import & activate caddy obtained certificate
/mnt/nas/adm/caddy/cert.sh
Code:
#!/bin/sh
apiKey="***"
url="https://192.168.0.5/api/v2.0"
name="caddy-$(date +%s)"
folder=/mnt/nas/adm/caddy
domain=example.org

data()
{
  cat <<EOF
 {
  "create_type": "CERTIFICATE_CREATE_IMPORTED",
  "name": "$name",
  "certificate": "$(find $folder -type f -name "$domain.crt" -exec cat {} + | awk '{printf "%s\\n", $0}')",
  "privatekey": "$(find $folder -type f -name "$domain.key" -exec cat {} + | awk '{printf "%s\\n", $0}')"
 }
EOF
}

#import cert
curl -sk -H "Authorization: Bearer $apiKey" -H "Content-Type: application/json" -d "$(data)" "$url/certificate" > /dev/null

#get imported cert id
id="$(curl -sk -H "Authorization: Bearer $apiKey" "$url/certificate" | jq -r '.[] | select(.name=="'$name'") | .id')"

if [ -n ${id} ]; then
  #get id for current FTP cert
  id2="$(curl -sk -H "Authorization: Bearer $apiKey" "$url/ftp" | jq .ssltls_certificate)"
  #activate new cert for FTP
  curl -sk -H "Authorization: Bearer $apiKey" -H "Content-Type: application/json" -d "{\"ssltls_certificate\": $id}" -X PUT "$url/ftp" > /dev/null
  #delte previous cert
  if [ -n ${id2} ]; then curl -sk -H "Authorization: Bearer $apiKey" -X DELETE "$url/certificate/id/$id2" > /dev/null; fi
 else
   echo "cert id not found!"
fi


make scripts executable
Code:
chmod +x /mnt/nas/adm/caddy/cert.sh


import cert periodically
Tasks->Cron Jobs
Description: Caddy cert import
Command: /mnt/nas/adm/caddy/cert.sh
Run As User: root
Schedule: Weekly
 

Patrick M. Hausen

Hall of Famer
Joined
Nov 25, 2013
Messages
7,776
I wasn't able to change kern.ipc.maxsockbuf in jail
That's a kernel setting so it must be set on the host. Since all jails share the same kernel it will also apply to all jails.
 
Top