caddy-2.6.2/000077500000000000000000000000001435007237400126125ustar00rootroot00000000000000caddy-2.6.2/LICENSE000066400000000000000000000261361435007237400136270ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. caddy-2.6.2/README.md000066400000000000000000000020461435007237400140730ustar00rootroot00000000000000Caddy Distribution Resources ============================ This repository contains official resources for packaging and distributing [Caddy](https://github.com/caddyserver/caddy). Note that packages or distributions which _use_ these resources are not necessarily endorsed by the Caddy project (but the ones listed below are). ## List of official Caddy distributions These distributions are endorsed and maintained by the Caddy project: - [GitHub releases](https://github.com/caddyserver/caddy/releases) - [Docker](https://hub.docker.com/_/caddy) - [Fedora COPR](https://copr.fedorainfracloud.org/coprs/g/caddy/caddy/) - [Debian (hosting provided by Cloudsmith)](https://cloudsmith.io/~caddy/repos/) - [DigitalOcean](https://marketplace.digitalocean.com/apps/caddy) ## Installing Caddy For instructions on installing Caddy, please see [our installation guide](https://caddyserver.com/docs/install). ## We need help with packaging Do you have experience packaging Go programs for any platforms? Please reach out to us in an issue, we'd love your help! caddy-2.6.2/config/000077500000000000000000000000001435007237400140575ustar00rootroot00000000000000caddy-2.6.2/config/Caddyfile000066400000000000000000000014011435007237400156620ustar00rootroot00000000000000# The Caddyfile is an easy way to configure your Caddy web server. # # Unless the file starts with a global options block, the first # uncommented line is always the address of your site. # # To use your own domain name (with automatic HTTPS), first make # sure your domain's A/AAAA DNS records are properly pointed to # this machine's public IP, then replace ":80" below with your # domain name. :80 { # Set this path to your site's directory. root * /usr/share/caddy # Enable the static file server. file_server # Another common task is to set up a reverse proxy: # reverse_proxy localhost:8080 # Or serve a PHP site through php-fpm: # php_fastcgi localhost:9000 } # Refer to the Caddy docs for more information: # https://caddyserver.com/docs/caddyfile caddy-2.6.2/init/000077500000000000000000000000001435007237400135555ustar00rootroot00000000000000caddy-2.6.2/init/README.md000066400000000000000000000103171435007237400150360ustar00rootroot00000000000000Official service files for systemd ================================== This folder contains the officially-maintained systemd files that should be used as a basis for your own deployments. **⚠️ Always review your service file before using it! Change anything that you need to customize.** ## Instructions See our website for [installation instructions](https://caddyserver.com/docs/install). ## Prerequisites Running Caddy as a systemd service requires the following: Group named `caddy`: ```bash $ groupadd --system caddy ``` User named `caddy` with a writeable home folder: ```bash $ useradd --system \ --gid caddy \ --create-home \ --home-dir /var/lib/caddy \ --shell /usr/sbin/nologin \ --comment "Caddy web server" \ caddy ``` ## Choosing a service file - **`caddy.service`** - Use this one if you configure Caddy with a file (for example, the Caddyfile, or a .json file). - **`caddy-api.service`** - Use this one if you configure Caddy solely through its API. The two files are identical except for the ExecStart and ExecReload commands. The usual place to save the service file is: `/etc/systemd/system/caddy.service` ## Important Caddy receives all configuration through its [admin API](https://caddyserver.com/docs/api), even when the [command line interface (CLI)](https://caddyserver.com/docs/command-line) is used, which simply wraps up the API calls for you. Most users will use either config files and the CLI [mutually exclusively](https://caddyserver.com/docs/getting-started#api-vs-config-files) with the API because it is simpler to have only one source of truth. However, you may wish to provide Caddy an initial "bootstrapping" configuration with a config file, and use the API thereafter. **⚠️ If you provide an initial config file with the `--config` flag and then update the config using the API, you risk losing your changes if the service is restarted unless you have the `--resume` flag in your ExecStart command.** Without the `--resume` flag, the `--config` flag will overwrite any last-known configuration. However, it is totally safe and normal to use both the `--config` and `--resume` options together if you need to use both a config file and the API. Just be aware that if you update your config file and want to apply those changes, _stopping and starting the server is the wrong way to do this_. Restarting the service is orthogonal to config changes; this is a unique safety feature that guarantees durability and prevents data loss. If the config file has the latest changes, you should use the reload command instead. ## Explanation of directives To keep our unit files tidy, we haven't littered them with comments. So here we explain the [parameters we've chosen](https://github.com/caddyserver/dist/pull/1): - **`After=network.target network-online.target`** and **`Requires=network-online.target`** ensures that the network interfaces are online before Caddy starts. This is necessary because Caddy uses the network to obtain certificates and serve your site over TLS. Specifically, `network-online.target` is needed for the many users who bind listeners to specific network interfaces. - **`TimeoutStopSec=5s`** will forcibly kill the caddy process if it cannot gracefully shut down within this time limit. We figure, if you're stopping the server anyway (as opposed to reloading -- two very distinct operations!) then stopping gracefully is less important than stopping at all. - **`LimitNOFILE=1048576`** raises the file descriptor limit for the caddy process (`ulimit -n`). This is very important for busy sites, or for servers which need to keep connections open longer. This is the [maximum allowed value](https://stackoverflow.com/a/1213069/1048862) for some popular Linux distros. - **`LimitNPROC=512`** raises the number of threads caddy is allowed to have (`ulimit -u`). Obviously, setting this too low for a highly concurrent server is a bad idea. - **`PrivateTmp=true`** keeps /tmp and /var/tmp private, which are discarded after caddy stops. - **`ProtectSystem=full`** allows writing to /var, which is crucial so that it can store certificates and other data for your site. - **`AmbientCapabilities=CAP_NET_BIND_SERVICE`** allows caddy to bind to low ports (< 1024) without running as root. caddy-2.6.2/init/caddy-api.service000066400000000000000000000012071435007237400167720ustar00rootroot00000000000000# caddy-api.service # # For using Caddy with its API. # # This unit is "durable" in that it will automatically resume # the last active configuration if the service is restarted. # # See https://caddyserver.com/docs/install for instructions. [Unit] Description=Caddy Documentation=https://caddyserver.com/docs/ After=network.target network-online.target Requires=network-online.target [Service] Type=notify User=caddy Group=caddy ExecStart=/usr/bin/caddy run --environ --resume TimeoutStopSec=5s LimitNOFILE=1048576 LimitNPROC=512 PrivateTmp=true ProtectSystem=full AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target caddy-2.6.2/init/caddy.service000066400000000000000000000020061435007237400162210ustar00rootroot00000000000000# caddy.service # # For using Caddy with a config file. # # Make sure the ExecStart and ExecReload commands are correct # for your installation. # # See https://caddyserver.com/docs/install for instructions. # # WARNING: This service does not use the --resume flag, so if you # use the API to make changes, they will be overwritten by the # Caddyfile next time the service is restarted. If you intend to # use Caddy's API to configure it, add the --resume flag to the # `caddy run` command or use the caddy-api.service file instead. [Unit] Description=Caddy Documentation=https://caddyserver.com/docs/ After=network.target network-online.target Requires=network-online.target [Service] Type=notify User=caddy Group=caddy ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force TimeoutStopSec=5s LimitNOFILE=1048576 LimitNPROC=512 PrivateTmp=true ProtectSystem=full AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target caddy-2.6.2/packer/000077500000000000000000000000001435007237400140575ustar00rootroot00000000000000caddy-2.6.2/packer/README.md000066400000000000000000000013331435007237400153360ustar00rootroot00000000000000Caddy Packer Template for DigitalOcean Image ============================================ This helps build the DigitalOcean droplet image for their marketplace. ## Requirements - Packer 1.6 or newer - Ansible To run the script: ```bash packer init DIGITALOCEAN_TOKEN=foobar packer build do-marketplace-image.pkr.hcl ``` Be sure to replace `foobar` with your DigitalOcean API key. The scripts `90-cleanup.sh` and `99-img_check.sh` are from [DO's own repo](https://github.com/digitalocean/marketplace-partners/tree/master/scripts). The droplet is hardened with these roles: - [dev-sec.os-hardening](https://github.com/dev-sec/ansible-os-hardening) - [dev-sec.ssh-hardening](https://github.com/dev-sec/ansible-ssh-hardening) caddy-2.6.2/packer/ansible/000077500000000000000000000000001435007237400154745ustar00rootroot00000000000000caddy-2.6.2/packer/ansible/ansible-playbook.yml000066400000000000000000000011361435007237400214530ustar00rootroot00000000000000- hosts: all user: root roles: - dev-sec.os-hardening - dev-sec.ssh-hardening vars: sysctl_overwrite: net.ipv6.conf.all.disable_ipv6: 0 ufw_manage_defaults: false # we're managing the default ufw in scripts/10-firewall.sh os_filesystem_whitelist: "vfat" # the EFI partition is formatted with this filesystem # Digital Ocean doesn't disable the option, regardless of whether the # image supports it, so we must enable it. # see: https://caddy.community/t/cannot-sign-in-to-digitalocean-droplet/6963 ssh_permit_root_login: "yes" ssh_max_auth_retries: 100 caddy-2.6.2/packer/ansible/requirements.yml000066400000000000000000000001661435007237400207450ustar00rootroot00000000000000--- collections: [] roles: - src: dev-sec.os-hardening version: 6.0.3 - src: dev-sec.ssh-hardening version: 9.3.0 caddy-2.6.2/packer/do-marketplace-image.pkr.hcl000066400000000000000000000030041435007237400213070ustar00rootroot00000000000000packer { required_plugins { digitalocean = { version = ">= 1.0.0" source = "github.com/hashicorp/digitalocean" } } } variable "token" { type = string default = env("DIGITALOCEAN_TOKEN") } # "timestamp" template function replacement locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } # All locals variables are generated from variables that uses expressions # that are not allowed in HCL2 variables. # Read the documentation for locals blocks here: # https://www.packer.io/docs/templates/hcl_templates/blocks/locals locals { image_name = "marketplace-snapshot-${local.timestamp}" ssh_user = "root" } source "digitalocean" "caddy_image" { api_token = var.token image = "ubuntu-20-04-x64" region = "nyc3" size = "s-1vcpu-1gb" snapshot_name = local.image_name ssh_username = local.ssh_user } build { sources = ["source.digitalocean.caddy_image"] provisioner "shell" { scripts = [ "scripts/00-base.sh", "scripts/10-firewall.sh", "scripts/20-caddy.sh" ] } provisioner "file" { destination = "/etc/fail2ban/jail.local" source = "files/fail2ban/jail.local" } provisioner "ansible" { galaxy_file = "ansible/requirements.yml" playbook_file = "ansible/ansible-playbook.yml" user = local.ssh_user } provisioner "shell" { scripts = [ "scripts/50-services.sh", "scripts/90-cleanup.sh", "scripts/95-prep.sh", "scripts/99-img_check.sh" ] } } caddy-2.6.2/packer/files/000077500000000000000000000000001435007237400151615ustar00rootroot00000000000000caddy-2.6.2/packer/files/fail2ban/000077500000000000000000000000001435007237400166375ustar00rootroot00000000000000caddy-2.6.2/packer/files/fail2ban/jail.local000066400000000000000000000001261435007237400205710ustar00rootroot00000000000000[sshd] enabled = true port = 22 filter = sshd logpath = /var/log/auth.log maxretry = 5caddy-2.6.2/packer/scripts/000077500000000000000000000000001435007237400155465ustar00rootroot00000000000000caddy-2.6.2/packer/scripts/00-base.sh000066400000000000000000000002501435007237400172260ustar00rootroot00000000000000#!/bin/bash apt-get update -y DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y -q apt install -y unattended-upgrades fail2ban apt autoremove -y apt autoclean -y caddy-2.6.2/packer/scripts/10-firewall.sh000066400000000000000000000002051435007237400201220ustar00rootroot00000000000000#!/bin/bash ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw allow http ufw allow https echo "y" | ufw enable caddy-2.6.2/packer/scripts/20-caddy.sh000066400000000000000000000005671435007237400174150ustar00rootroot00000000000000#!/bin/bash set -eux; curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list apt update apt install caddy mkdir -p /var/www/html chown -R caddy:caddy /var/www caddy-2.6.2/packer/scripts/50-services.sh000066400000000000000000000002071435007237400201460ustar00rootroot00000000000000#!/bin/bash systemctl daemon-reload systemctl enable fail2ban systemctl start fail2ban systemctl enable caddy systemctl start caddy caddy-2.6.2/packer/scripts/90-cleanup.sh000066400000000000000000000023651435007237400177650ustar00rootroot00000000000000#!/bin/bash # Ensure /tmp exists and has the proper permissions before # checking for security updates # https://github.com/digitalocean/marketplace-partners/issues/94 if [[ ! -d /tmp ]]; then mkdir /tmp fi chmod 1777 /tmp apt-get -y update apt-get -y upgrade rm -rf /tmp/* /var/tmp/* history -c cat /dev/null > /root/.bash_history unset HISTFILE apt-get -y autoremove apt-get -y autoclean find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? rm -rf /var/lib/cloud/instances/* rm -f /root/.ssh/authorized_keys /etc/ssh/*key* touch /etc/ssh/revoked_keys chmod 600 /etc/ssh/revoked_keys # Securely erase the unused portion of the filesystem GREEN='\033[0;32m' NC='\033[0m' printf "\n${GREEN}Writing zeros to the remaining disk space to securely erase the unused portion of the file system. Depending on your disk size this may take several minutes. The secure erase will complete successfully when you see:${NC} dd: writing to '/zerofile': No space left on device\n Beginning secure erase now\n" dd if=/dev/zero of=/zerofile & PID=$! while [ -d /proc/$PID ] do printf "." sleep 5 done sync; rm /zerofile; sync cat /dev/null > /var/log/lastlog; cat /dev/null > /var/log/wtmp caddy-2.6.2/packer/scripts/95-prep.sh000066400000000000000000000001311435007237400172760ustar00rootroot00000000000000#!/bin/bash rm /var/log/*.log rm -rf /var/log/unattended-upgrades rm -rf /root/.ansible caddy-2.6.2/packer/scripts/99-img_check.sh000066400000000000000000000572041435007237400202620ustar00rootroot00000000000000#!/bin/bash # # DigitalOcean Marketplace Image Validation Tool # © 2018 DigitalOcean LLC. # This code is licensed under MIT license (see LICENSE.txt for details) # VERSION="v. 1.5" RUNDATE=$( date ) # Script should be run with SUDO if [ "$EUID" -ne 0 ] then echo "[Error] - This script must be run with sudo or as the root user." exit 1 fi STATUS=0 PASS=0 WARN=0 FAIL=0 # $1 == command to check for # returns: 0 == true, 1 == false cmdExists() { if command -v "$1" > /dev/null 2>&1; then return 0 else return 1 fi } function getDistro { if [ -f /etc/os-release ]; then # freedesktop.org and systemd . /etc/os-release OS=$NAME VER=$VERSION_ID elif type lsb_release >/dev/null 2>&1; then # linuxbase.org OS=$(lsb_release -si) VER=$(lsb_release -sr) elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command . /etc/lsb-release OS=$DISTRIB_ID VER=$DISTRIB_RELEASE elif [ -f /etc/debian_version ]; then # Older Debian/Ubuntu/etc. OS=Debian VER=$(cat /etc/debian_version) elif [ -f /etc/SuSe-release ]; then # Older SuSE/etc. : elif [ -f /etc/redhat-release ]; then # Older Red Hat, CentOS, etc. VER=$( cat /etc/redhat-release | cut -d" " -f3 | cut -d "." -f1) d=$( cat /etc/redhat-release | cut -d" " -f1 | cut -d "." -f1) if [[ $d == "CentOS" ]]; then OS="CentOS Linux" fi else # Fall back to uname, e.g. "Linux ", also works for BSD, etc. OS=$(uname -s) VER=$(uname -r) fi } function loadPasswords { SHADOW=$(cat /etc/shadow) } function checkAgent { # Check for the presence of the do-agent in the filesystem if [ -d /var/opt/digitalocean/do-agent ];then echo -en "\e[41m[FAIL]\e[0m DigitalOcean Monitoring Agent detected.\n" ((FAIL++)) STATUS=2 if [[ $OS == "CentOS Linux" ]]; then echo "The agent can be removed with 'sudo yum remove do-agent' " elif [[ $OS == "Ubuntu" ]]; then echo "The agent can be removed with 'sudo apt-get purge do-agent' " fi else echo -en "\e[32m[PASS]\e[0m DigitalOcean Monitoring agent was not found\n" ((PASS++)) fi } function checkLogs { cp_ignore="/var/log/cpanel-install.log" echo -en "\nChecking for log files in /var/log\n\n" # Check if there are log archives or log files that have not been recently cleared. for f in /var/log/*-????????; do [[ -e $f ]] || break if [ $f != $cp_ignore ]; then echo -en "\e[93m[WARN]\e[0m Log archive ${f} found\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi done for f in /var/log/*.[0-9];do [[ -e $f ]] || break echo -en "\e[93m[WARN]\e[0m Log archive ${f} found\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi done for f in /var/log/*.log; do [[ -e $f ]] || break if [[ "${f}" = '/var/log/lfd.log' && "$( cat "${f}" | egrep -v '/var/log/messages has been reset| Watching /var/log/messages' | wc -c)" -gt 50 ]]; then if [ $f != $cp_ignore ]; then echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi elif [[ "${f}" != '/var/log/lfd.log' && "$( cat "${f}" | wc -c)" -gt 50 ]]; then if [ $f != $cp_ignore ]; then echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi fi done } function checkTMP { # Check the /tmp directory to ensure it is empty. Warn on any files found. return 1 } function checkRoot { user="root" uhome="/root" for usr in $SHADOW do IFS=':' read -r -a u <<< "$usr" if [[ "${u[0]}" == "${user}" ]]; then if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then echo -en "\e[32m[PASS]\e[0m User ${user} has no password set.\n" ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m User ${user} has a password set on their account.\n" ((FAIL++)) STATUS=2 fi fi done if [ -d ${uhome}/ ]; then if [ -d ${uhome}/.ssh/ ]; then if ls ${uhome}/.ssh/*> /dev/null 2>&1; then for key in ${uhome}/.ssh/* do if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" akey=$(cat ${key}) echo "File Contents:" echo $akey echo "--------------" ((FAIL++)) STATUS=2 fi elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then if [ "$( cat "${key}" | wc -c)" -gt 0 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" akey=$(cat ${key}) echo "File Contents:" echo $akey echo "--------------" ((FAIL++)) STATUS=2 else echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has empty private key file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi elif [ "${key}" != "${uhome}/.ssh/known_hosts" ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a file in their .ssh directory at \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi else if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a populated known_hosts file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi fi done else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m has no SSH keys present\n" fi else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have an .ssh directory\n" fi if [ -f /root/.bash_history ];then BH_S=$( cat /root/.bash_history | wc -c) if [[ $BH_S -lt 200 ]]; then echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m ${user}'s Bash History should be cleared to prevent sensitive information from leaking\n" ((FAIL++)) STATUS=2 fi return 1; else echo -en "\e[32m[PASS]\e[0m The Root User's Bash History is not present\n" ((PASS++)) fi else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have a directory in /home\n" fi echo -en "\n\n" return 1 } function checkUsers { # Check each user-created account for user in $(awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd;) do # Skip some other non-user system accounts if [[ $user == "centos" ]]; then : elif [[ $user == "nfsnobody" ]]; then : else echo -en "\nChecking user: ${user}...\n" for usr in $SHADOW do IFS=':' read -r -a u <<< "$usr" if [[ "${u[0]}" == "${user}" ]]; then if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then echo -en "\e[32m[PASS]\e[0m User ${user} has no password set.\n" ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m User ${user} has a password set on their account. Only system users are allowed on the image.\n" ((FAIL++)) STATUS=2 fi fi done #echo "User Found: ${user}" uhome="/home/${user}" if [ -d "${uhome}/" ]; then if [ -d "${uhome}/.ssh/" ]; then if ls "${uhome}/.ssh/*"> /dev/null 2>&1; then for key in ${uhome}/.ssh/* do if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" akey=$(cat ${key}) echo "File Contents:" echo $akey echo "--------------" ((FAIL++)) STATUS=2 fi elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then if [ "$( cat "${key}" | wc -c)" -gt 0 ]; then echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" akey=$(cat ${key}) echo "File Contents:" echo $akey echo "--------------" ((FAIL++)) STATUS=2 else echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has empty private key file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi elif [ "${key}" != "${uhome}/.ssh/known_hosts" ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a file in their .ssh directory named \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi else if [ "$( cat "${key}" | wc -c)" -gt 50 ]; then echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a known_hosts file in \e[93m${key}\e[0m\n" ((WARN++)) if [[ $STATUS != 2 ]]; then STATUS=1 fi fi fi done else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m has no SSH keys present\n" fi else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have an .ssh directory\n" fi else echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have a directory in /home\n" fi # Check for an uncleared .bash_history for this user if [ -f "${uhome}/.bash_history" ]; then BH_S=$( cat "${uhome}/.bash_history" | wc -c ) if [[ $BH_S -lt 200 ]]; then echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m ${user}'s Bash History should be cleared to prevent sensitive information from leaking\n" ((FAIL++)) STATUS=2 fi echo -en "\n\n" fi fi done } function checkFirewall { if [[ $OS == "Ubuntu" ]]; then fw="ufw" ufwa=$(ufw status |head -1| sed -e "s/^Status:\ //") if [[ $ufwa == "active" ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi elif [[ $OS == "CentOS Linux" ]]; then if [ -f /usr/lib/systemd/system/csf.service ]; then fw="csf" if [[ $(systemctl status $fw >/dev/null 2>&1) ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) elif cmdExists "firewall-cmd"; then if [[ $(systemctl is-active firewalld >/dev/null 2>&1 && echo 1 || echo 0) ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi else fw="firewalld" if [[ $(systemctl is-active firewalld >/dev/null 2>&1 && echo 1 || echo 0) ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi fi elif [[ "$OS" =~ Debian.* ]]; then # user could be using a number of different services for managing their firewall # we will check some of the most common if cmdExists 'ufw'; then fw="ufw" ufwa=$(ufw status | sed -e "s/^Status:\ //") if [[ $ufwa == "active" ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi elif cmdExists "firewall-cmd"; then fw="firewalld" if [[ $(systemctl is-active --quiet $fw) ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi else # user could be using vanilla iptables, check if kernel module is loaded fw="iptables" if [[ $(lsmod | grep -q '^ip_tables' 2>/dev/null) ]]; then FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" ((PASS++)) else FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" ((WARN++)) fi fi fi } function checkUpdates { if [[ $OS == "Ubuntu" ]] || [[ "$OS" =~ Debian.* ]]; then # Ensure /tmp exists and has the proper permissions before # checking for security updates # https://github.com/digitalocean/marketplace-partners/issues/94 if [[ ! -d /tmp ]]; then mkdir /tmp fi chmod 1777 /tmp echo -en "\nUpdating apt package database to check for security updates, this may take a minute...\n\n" apt-get -y update > /dev/null uc=$(apt-get --just-print upgrade | grep -i "security" | wc -l) if [[ $uc -gt 0 ]]; then update_count=$(( ${uc} / 2 )) else update_count=0 fi if [[ $update_count -gt 0 ]]; then echo -en "\e[41m[FAIL]\e[0m There are ${update_count} security updates available for this image that have not been installed.\n" echo -en echo -en "Here is a list of the security updates that are not installed:\n" sleep 2 apt-get --just-print upgrade | grep -i security | awk '{print $2}' | awk '!seen[$0]++' echo -en ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m There are no pending security updates for this image.\n\n" fi elif [[ $OS == "CentOS Linux" ]]; then echo -en "\nChecking for available updates with yum, this may take a minute...\n\n" update_count=$(yum list updates -q | grep -vc "Updated Packages") if [[ $update_count -gt 0 ]]; then echo -en "\e[41m[FAIL]\e[0m There are ${update_count} updates available for this image that have not been installed.\n" ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m There are no pending security updates for this image.\n" ((PASS++)) fi else echo "Error encountered" exit 1 fi return 1; } function checkCloudInit { if hash cloud-init 2>/dev/null; then CI="\e[32m[PASS]\e[0m Cloud-init is installed.\n" ((PASS++)) else CI="\e[41m[FAIL]\e[0m No valid verison of cloud-init was found.\n" ((FAIL++)) STATUS=2 fi return 1 } function checkMongoDB { # Check if MongoDB is installed # If it is, verify the version is allowed (non-SSPL) if [[ $OS == "Ubuntu" ]] || [[ "$OS" =~ Debian.* ]]; then if [[ -f "/usr/bin/mongod" ]]; then version=$(/usr/bin/mongod --version --quiet | grep "db version" | sed -e "s/^db\ version\ v//") if version_gt $version 4.0.0; then if version_gt $version 4.0.3; then echo -en "\e[41m[FAIL]\e[0m An SSPL version of MongoDB is present, ${version}" ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m The version of MongoDB installed, ${version} is not under the SSPL" ((PASS++)) fi else if version_gt $version 3.6.8; then echo -en "\e[41m[FAIL]\e[0m An SSPL version of MongoDB is present, ${version}" ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m The version of MongoDB installed, ${version} is not under the SSPL" ((PASS++)) fi fi else echo -en "\e[32m[PASS]\e[0m MongoDB is not installed" ((PASS++)) fi elif [[ $OS == "CentOS Linux" ]]; then if [[ -f "/usr/bin/mongod" ]]; then version=$(/usr/bin/mongod --version --quiet | grep "db version" | sed -e "s/^db\ version\ v//") if version_gt $version 4.0.0; then if version_gt $version 4.0.3; then echo -en "\e[41m[FAIL]\e[0m An SSPL version of MongoDB is present" ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m The version of MongoDB installed is not under the SSPL" ((PASS++)) fi else if version_gt $version 3.6.8; then echo -en "\e[41m[FAIL]\e[0m An SSPL version of MongoDB is present" ((FAIL++)) STATUS=2 else echo -en "\e[32m[PASS]\e[0m The version of MongoDB installed is not under the SSPL" ((PASS++)) fi fi else echo -en "\e[32m[PASS]\e[0m MongoDB is not installed" ((PASS++)) fi else echo "ERROR: Unable to identify distribution" ((FAIL++)) STATUS 2 return 1 fi } function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } clear echo "DigitalOcean Marketplace Image Validation Tool ${VERSION}" echo "Executed on: ${RUNDATE}" echo "Checking local system for Marketplace compatibility..." getDistro echo -en "\n\e[1mDistribution:\e[0m ${OS}\n" echo -en "\e[1mVersion:\e[0m ${VER}\n\n" ost=0 osv=0 if [[ $OS == "Ubuntu" ]]; then ost=1 if [[ $VER == "20.04" ]]; then osv=1 elif [[ $VER == "18.04" ]]; then osv=1 elif [[ $VER == "16.04" ]]; then osv=1 else osv=0 fi elif [[ "$OS" =~ Debian.* ]]; then ost=1 case "$VER" in 9) osv=1 ;; 10) osv=1 ;; *) osv=2 ;; esac elif [[ $OS == "CentOS Linux" ]]; then ost=1 if [[ $VER == "8" ]]; then osv=1 elif [[ $VER == "7" ]]; then osv=1 elif [[ $VER == "6" ]]; then osv=1 else osv=2 fi else ost=0 fi if [[ $ost == 1 ]]; then echo -en "\e[32m[PASS]\e[0m Supported Operating System Detected: ${OS}\n" ((PASS++)) else echo -en "\e[41m[FAIL]\e[0m ${OS} is not a supported Operating System\n" ((FAIL++)) STATUS=2 fi if [[ $osv == 1 ]]; then echo -en "\e[32m[PASS]\e[0m Supported Release Detected: ${VER}\n" ((PASS++)) elif [[ $ost == 1 ]]; then echo -en "\e[41m[FAIL]\e[0m ${OS} ${VER} is not a supported Operating System Version\n" ((FAIL++)) STATUS=2 else echo "Exiting..." exit 1 fi checkCloudInit echo -en "${CI}" checkFirewall echo -en "${FW_VER}" checkUpdates loadPasswords checkLogs echo -en "\n\nChecking all user-created accounts...\n" checkUsers echo -en "\n\nChecking the root account...\n" checkRoot checkAgent checkMongoDB # Summary echo -en "\n\n---------------------------------------------------------------------------------------------------\n" if [[ $STATUS == 0 ]]; then echo -en "Scan Complete.\n\e[32mAll Tests Passed!\e[0m\n" elif [[ $STATUS == 1 ]]; then echo -en "Scan Complete. \n\e[93mSome non-critical tests failed. Please review these items.\e[0m\e[0m\n" else echo -en "Scan Complete. \n\e[41mOne or more tests failed. Please review these items and re-test.\e[0m\n" fi echo "---------------------------------------------------------------------------------------------------" echo -en "\e[1m${PASS} Tests PASSED\e[0m\n" echo -en "\e[1m${WARN} WARNINGS\e[0m\n" echo -en "\e[1m${FAIL} Tests FAILED\e[0m\n" echo -en "---------------------------------------------------------------------------------------------------\n" if [[ $STATUS == 0 ]]; then echo -en "We did not detect any issues with this image. Please be sure to manually ensure that all software installed on the base system is functional, secure and properly configured (or facilities for configuration on first-boot have been created).\n\n" exit 0 elif [[ $STATUS == 1 ]]; then echo -en "Please review all [WARN] items above and ensure they are intended or resolved. If you do not have a specific requirement, we recommend resolving these items before image submission\n\n" exit 1 else echo -en "Some critical tests failed. These items must be resolved and this scan re-run before you submit your image to the marketplace.\n\n" exit 1 fi caddy-2.6.2/rpm/000077500000000000000000000000001435007237400134105ustar00rootroot00000000000000caddy-2.6.2/rpm/caddy.spec000066400000000000000000000216121435007237400153520ustar00rootroot00000000000000%global debug_package %{nil} %global basever 2.6.1 #global prerel rc #global prerelnum 3 %global tag v%{basever}%{?prerel:-%{prerel}.%{prerelnum}} Name: caddy # https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/#_versioning_prereleases_with_tilde Version: %{basever}%{?prerel:~%{prerel}%{prerelnum}} Release: 1%{?dist} Summary: Web server with automatic HTTPS License: ASL 2.0 URL: https://caddyserver.com # In order to build Caddy with version information, we need to import it as a # go module. To do that, we are going to forgo the traditional source tarball # and instead use just this file from upstream. This method requires that we # allow networking in the build environment. Source0: https://raw.githubusercontent.com/caddyserver/caddy/%{tag}/cmd/caddy/main.go # Use official resources for config, unit file, and welcome page. # https://github.com/caddyserver/dist Source1: https://raw.githubusercontent.com/caddyserver/dist/master/config/Caddyfile Source2: https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service Source3: https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy-api.service Source4: https://raw.githubusercontent.com/caddyserver/dist/master/welcome/index.html # Since we are not using a traditional source tarball, we need to explicitly # pull in the license file. Source10: https://raw.githubusercontent.com/caddyserver/caddy/%{tag}/LICENSE # https://github.com/caddyserver/caddy/commit/141872ed80d6323505e7543628c259fdae8506d3 BuildRequires: golang >= 1.18 BuildRequires: git-core %if 0%{?rhel} && 0%{?rhel} < 8 BuildRequires: systemd %else BuildRequires: systemd-rpm-macros %endif %{?systemd_requires} Provides: webserver %description Caddy is the web server with automatic HTTPS. %prep %setup -q -c -T # Copy main.go and LICENSE into the build directory. cp %{S:0} %{S:10} . %build # https://pagure.io/go-rpm-macros/c/1cc7f5d9026175bb6cb1b8c889355d0c4fc0e40a %undefine _auto_set_build_flags # Fedora diverges from upstream Go by disabling the proxy server. Some of # Caddy's dependencies reference commits that are no longer upstream, but are # cached in the proxy. As long as we are downloading dependencies during the # build, reset the behavior to prefer the proxy. This also avoid having a # build requirement on bzr. # https://fedoraproject.org/wiki/Changes/golang1.13#Detailed_Description export GOPROXY='https://proxy.golang.org,direct' go mod init caddy echo "require github.com/caddyserver/caddy/v2 %{tag}" >> go.mod go mod tidy go build \ -buildmode pie \ -compiler gc \ %{!?suse_version: -tags="rpm_crashtraceback ${BUILDTAGS:-}"} \ -ldflags "${LDFLAGS:-} -B 0x$(head -c20 /dev/urandom|od -An -tx1|tr -d ' \n')%{?__global_ldflags: -extldflags '%__global_ldflags'}" \ -a -v -x %install # command install -D -p -m 0755 caddy %{buildroot}%{_bindir}/caddy # config install -D -p -m 0644 %{S:1} %{buildroot}%{_sysconfdir}/caddy/Caddyfile # systemd units install -D -p -m 0644 %{S:2} %{buildroot}%{_unitdir}/caddy.service install -D -p -m 0644 %{S:3} %{buildroot}%{_unitdir}/caddy-api.service # data directory install -d -m 0750 %{buildroot}%{_sharedstatedir}/caddy # welcome page install -D -p -m 0644 %{S:4} %{buildroot}%{_datadir}/caddy/index.html # shell completion install -d -m 0755 %{buildroot}%{_datadir}/bash-completion/completions ./caddy completion bash > %{buildroot}%{_datadir}/bash-completion/completions/caddy install -d -m 0755 %{buildroot}%{_datadir}/zsh/site-functions ./caddy completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_caddy # man pages ./caddy manpage --directory %{buildroot}%{_mandir}/man8/ %pre getent group caddy &> /dev/null || \ groupadd -r caddy &> /dev/null getent passwd caddy &> /dev/null || \ useradd -r -g caddy -d %{_sharedstatedir}/caddy -s /sbin/nologin -c 'Caddy web server' caddy &> /dev/null exit 0 %post %systemd_post caddy.service if [ -x /usr/sbin/getsebool ]; then # connect to ACME endpoint to request certificates setsebool -P httpd_can_network_connect on fi if [ -x /usr/sbin/semanage -a -x /usr/sbin/restorecon ]; then # file contexts semanage fcontext --add --type httpd_exec_t '%{_bindir}/caddy' 2> /dev/null || : semanage fcontext --add --type httpd_sys_content_t '%{_datadir}/caddy(/.*)?' 2> /dev/null || : semanage fcontext --add --type httpd_config_t '%{_sysconfdir}/caddy(/.*)?' 2> /dev/null || : semanage fcontext --add --type httpd_var_lib_t '%{_sharedstatedir}/caddy(/.*)?' 2> /dev/null || : restorecon -r %{_bindir}/caddy %{_datadir}/caddy %{_sysconfdir}/caddy %{_sharedstatedir}/caddy || : fi if [ -x /usr/sbin/semanage ]; then # QUIC semanage port --add --type http_port_t --proto udp 80 2> /dev/null || : semanage port --add --type http_port_t --proto udp 443 2> /dev/null || : # admin endpoint semanage port --add --type http_port_t --proto tcp 2019 2> /dev/null || : fi %preun %systemd_preun caddy.service %postun %systemd_postun_with_restart caddy.service if [ $1 -eq 0 ]; then if [ -x /usr/sbin/getsebool ]; then # connect to ACME endpoint to request certificates setsebool -P httpd_can_network_connect off fi if [ -x /usr/sbin/semanage ]; then # file contexts semanage fcontext --delete --type httpd_exec_t '%{_bindir}/caddy' 2> /dev/null || : semanage fcontext --delete --type httpd_sys_content_t '%{_datadir}/caddy(/.*)?' 2> /dev/null || : semanage fcontext --delete --type httpd_config_t '%{_sysconfdir}/caddy(/.*)?' 2> /dev/null || : semanage fcontext --delete --type httpd_var_lib_t '%{_sharedstatedir}/caddy(/.*)?' 2> /dev/null || : # QUIC semanage port --delete --type http_port_t --proto udp 80 2> /dev/null || : semanage port --delete --type http_port_t --proto udp 443 2> /dev/null || : # admin endpoint semanage port --delete --type http_port_t --proto tcp 2019 2> /dev/null || : fi fi %files %license LICENSE %{_bindir}/caddy %{_datadir}/caddy %{_unitdir}/caddy.service %{_unitdir}/caddy-api.service %dir %{_sysconfdir}/caddy %config(noreplace) %{_sysconfdir}/caddy/Caddyfile %attr(0750,caddy,caddy) %dir %{_sharedstatedir}/caddy # filesystem owns all the parent directories here %{_datadir}/bash-completion/completions/caddy # own parent directories in case zsh is not installed %dir %{_datadir}/zsh %dir %{_datadir}/zsh/site-functions %{_datadir}/zsh/site-functions/_caddy %{_mandir}/man8/caddy*.8* %changelog * Thu Sep 22 2022 Carl George - 2.6.1-1 - Latest upstream * Wed Sep 21 2022 Carl George - 2.6.0-1 - Latest upstream * Tue Aug 09 2022 Carl George - 2.5.2-1 - Latest upstream * Fri May 06 2022 Carl George - 2.5.1-1 - Latest upstream * Thu May 05 2022 Carl George - 2.5.0-1 - Latest upstream * Mon Nov 08 2021 Neal Gompa - 2.4.6-1 - Latest upstream * Tue Oct 26 2021 Carl George - 2.4.5-1 - Latest upstream * Thu Jun 17 2021 Carl George - 2.4.3-1 - Latest upstream * Sat Jun 12 2021 Carl George - 2.4.2-1 - Latest upstream * Fri May 21 2021 Carl George - 2.4.1-1 - Latest upstream * Tue May 11 2021 Carl George - 2.4.0-1 - Latest upstream * Mon Jan 18 2021 Carl George - 2.3.0-1 - Latest upstream * Fri Oct 30 2020 Carl George - 2.2.1-1 - Latest upstream * Sat Sep 26 2020 Carl George - 2.2.0-1 - Latest upstream * Sat Sep 19 2020 Carl George - 2.2.0~rc3-1 - Latest upstream * Wed Sep 09 2020 Neal Gompa - 2.2.0~rc1-2 - Fix systemd build dependency for RHEL/CentOS * Mon Aug 31 2020 Carl George - 2.2.0~rc1-1 - Latest upstream - Add bash and zsh completion support * Wed Jul 08 2020 Neal Gompa - 2.1.1-1 - Latest upstream * Tue May 26 2020 Neal Gompa - 2.0.0-2 - Adapt for SUSE distributions * Wed May 06 2020 Neal Gompa - 2.0.0-1 - Update to v2.0.0 final * Sat Apr 18 2020 Carl George - 2.0.0~rc3-1 - Latest upstream * Sun Feb 02 2020 Carl George - 2.0.0~beta13-1 - Latest upstream * Mon Jan 06 2020 Carl George - 2.0.0~beta12-1 - Update to beta12 * Tue Nov 19 2019 Carl George - 2.0.0~beta10-1 - Update to beta10 * Wed Nov 06 2019 Carl George - 2.0.0~beta9-1 - Update to beta9 - Use upstream main.go file * Sun Nov 03 2019 Carl George - 2.0.0~beta8-1 - Update to beta8 * Sat Oct 19 2019 Carl George - 2.0.0~beta6-1 - Initial Caddy v2 package caddy-2.6.2/scripts/000077500000000000000000000000001435007237400143015ustar00rootroot00000000000000caddy-2.6.2/scripts/postinstall.sh000066400000000000000000000034571435007237400172220ustar00rootroot00000000000000#!/bin/sh set -e if [ "$1" = "configure" ]; then # Add user and group if ! getent group caddy >/dev/null; then groupadd --system caddy fi if ! getent passwd caddy >/dev/null; then useradd --system \ --gid caddy \ --create-home \ --home-dir /var/lib/caddy \ --shell /usr/sbin/nologin \ --comment "Caddy web server" \ caddy fi if getent group www-data >/dev/null; then usermod -aG www-data caddy fi # Add log directory with correct permissions if [ ! -d /var/log/caddy ]; then mkdir -p /var/log/caddy chown -R caddy:caddy /var/log/caddy fi fi if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then # This will only remove masks created by d-s-h on package removal. deb-systemd-helper unmask caddy.service >/dev/null || true deb-systemd-helper unmask caddy-api.service >/dev/null || true # was-enabled defaults to true, so new installations run enable. if deb-systemd-helper --quiet was-enabled caddy.service; then # Enables the unit on first installation, creates new # symlinks on upgrades if the unit file has changed. deb-systemd-helper enable caddy.service >/dev/null || true deb-systemd-invoke start caddy.service >/dev/null || true else # Update the statefile to add new symlinks (if any), which need to be # cleaned up on purge. Also remove old symlinks. deb-systemd-helper update-state caddy.service >/dev/null || true deb-systemd-helper update-state caddy-api.service >/dev/null || true fi # Restart only if it was already started if [ -d /run/systemd/system ]; then systemctl --system daemon-reload >/dev/null || true if [ -n "$2" ]; then deb-systemd-invoke try-restart caddy.service >/dev/null || true deb-systemd-invoke try-restart caddy-api.service >/dev/null || true fi fi ficaddy-2.6.2/scripts/postremove.sh000066400000000000000000000012101435007237400170320ustar00rootroot00000000000000#!/bin/sh set -e if [ -d /run/systemd/system ]; then systemctl --system daemon-reload >/dev/null || true fi if [ "$1" = "remove" ]; then if [ -x "/usr/bin/deb-systemd-helper" ]; then deb-systemd-helper mask caddy.service >/dev/null || true deb-systemd-helper mask caddy-api.service >/dev/null || true fi fi if [ "$1" = "purge" ]; then if [ -x "/usr/bin/deb-systemd-helper" ]; then deb-systemd-helper purge caddy.service >/dev/null || true deb-systemd-helper purge caddy-api.service >/dev/null || true deb-systemd-helper unmask caddy.service >/dev/null || true deb-systemd-helper unmask caddy-api.service >/dev/null || true fi ficaddy-2.6.2/scripts/preremove.sh000066400000000000000000000003051435007237400166370ustar00rootroot00000000000000#!/bin/sh set -e if [ -d /run/systemd/system ] && [ "$1" = remove ]; then deb-systemd-invoke stop caddy.service >/dev/null || true deb-systemd-invoke stop caddy-api.service >/dev/null || true ficaddy-2.6.2/welcome/000077500000000000000000000000001435007237400142455ustar00rootroot00000000000000caddy-2.6.2/welcome/index.html000066400000000000000000000277021435007237400162520ustar00rootroot00000000000000 Caddy works!

Congratulations! おめでとう! Felicidades! 恭喜! बधाई हो! Поздравляю!
 🎊

Your web server is working. Now make it work for you. 💪

Caddy is ready to serve your site over HTTPS:

  1. Point your domain's A/AAAA DNS records at this machine.
  2. Upload your site's files to /var/www/html.
  3. Edit your Caddyfile at /etc/caddy/Caddyfile:
    1. Replace :80 with your domain name
    2. Change the site root to /var/www/html
  4. Reload the configuration: systemctl reload caddy
  5. Visit your site!

If that worked 🥳

Awesome! You won't have to look at this slanted page anymore.

Remember, Caddy can do a lot more than serve static files. It's also a powerful reverse proxy and application platform. You can use the Caddyfile to enable any other features you need. Or you could use Caddy's API to configure it programmatically.

Everything you need to know is either in the 📖 Caddy documentation or the manual for your OS/platform. Have fun!

If that didn't work 😶

It's okay, you can fix it! First check the following things:

  • Service status: systemctl status caddy
  • Logs: journalctl --no-pager -u caddy
  • Are your site's files readable by the caddy user and group? ls -la /var/www/html
  • Is the caddy home directory writeable? ls -la /var/lib/caddy
  • Ensure your domain's A and/or AAAA records point to your machine's public IP address: dig example.com
  • Are your ports 80 and 443 externally reachable, and is Caddy able to bind to them? Check your firewalls, port forwarding, and other network configuration.

WAIT! Before trying again, switch to Let's Encrypt's staging environment to avoid being accidentally rate limited. Once you get everything else working, it's safe to switch back.

Depending on your DNS provider, it may take a while for the DNS records to propagate. Even when everything is configured properly, automated challenges to obtain TLS certificates usually take several seconds, but may take up to several minutes or hours.

If you still need help, we have a great community! First try a search, and if your question is original, go ahead and ask it! Remember to pay it forward and help others too. 😁

Visit Caddy on: GitHub or Twitter or Our Forum