Giter Club home page Giter Club logo

marketplace-partners's Introduction

DigitalOcean Marketplace Partner Tools

Apache license Pull Requests Welcome

This repository contains resources for DigitalOcean Marketplace partners, like documentation on image requirements and creation, tools for image cleanup and validation, and templates for build automation.

Getting Started creating your Kubernetes based 1-Click App

Please visit our Kubernetes Marketplace repo for instructions on how to create and submit your Kubernetes based 1-Click App.

Kubernetes 1-Click Apps can be submitted via our Marketplace Kubernetes Github repo.

Getting Started creating your Droplet based 1-Click App

The overall process for creating an image that you can submit as a Droplet based 1-Click App is as follows:

  1. Create and configure a build Droplet manually first to make sure your configuration works. You can create a build Droplet with any method, like the control panel, the API, or command-line tools like doctl. We strongly encourage you to use a $6 Droplet as your build Droplet. Using a $6 Droplet as your build Droplet will ensure that all Droplet types will be available for usage with your 1-Click App.

  2. Clean up and validate the build Droplet with the provided scripts, cleanup.sh and img_check.sh. The scripts will check for and fix potential security concerns and verify that the image will be compatible with Marketplace.

  3. Use Packer to create a fresh snapshot of the image that you want to create. While there are several ways to create an image, we recommend using Packer as the most simple and consistent option.

  4. Submit your final image to the Marketplace team for review. This can be made through our Vendor Portal. If you've signed expressed interest in joining the Marketplace through the form on this page but you've not received a login for the Vendor Portal, please reach out to [email protected] and we'll help you out.

  1. (Optional) Integrate a DigitalOcean Managed Database into your 1-Click App

    As a Vendor, you can offer a DigitalOcean Managed Database (DBaaS) to any DigitalOcean customer at the time they spin up your Droplet based 1-Click App. You can customize your app image to integrate with the managed database directly, or let your customers complete the configuration themselves after the 1-Click App boots up. This benefits your customers in terms of database scalability and ease of management, and reduces the burden of database support for you as a vendor.

    To enable this option, use the checkboxes that are shown in the Vendor Portal related to enablement of managed databases. If you’ve checked at least 1 box, when a user attempts to create your 1-Click App, they’ll receive a prompt like this one:

    dbaas_1_click_offer

    When a user selects the Managed Database option, DigitalOcean handles the creation of the database cluster as well as the user's Droplet. The Droplet will have a DATABASE_URL environment variable configured including a database connection string, such as:

    postgresql://doadmin:<password>@dbaas-db-11111-do-user-1111111-1.b.db.ondigitalocean.com:25060/defaultdb?sslmode=require

    The user’s managed database configuration and credentials will be stored in /root/.digitalocean_dbaas_credentials in the following format.

    db_protocol=
    db_username=
    db_password=
    db_host=
    db_port=
    db_database=
    

    To disable this feature for any new users of your 1-Click App, simply visit the Vendor Portal to edit your 1-Click App, removing the checkboxes next to all database engines. Once you save the edits, customers will no longer be given the option to add a managed database. Note that existing customers who have already deployed a managed database in conjunction with your 1-Click App will not be affected by that removal, and their managed databases will continue to operate.

Build Automation with Packer

Packer is a tool for creating images from a single source configuration. Using this Packer template reduces the entire process of creating, configuring, validating, and snapshotting a build Droplet to a single command:

packer build marketplace-image.json

By doing this, there is a reduced likelihood of having to submit an image multiple times as a result of falling in any of the next steps:

  • Installing OS updates
  • Deleting bash history.
  • Removing log files and SSH keys from the root user
  • Enabling the firewall (i.e. ufw if you use Ubuntu)

This repository is itself a Packer template for a LAMP stack. You can modify this template to use as a starting point for your image. Note that not all of the scripts/files in this repository are strictly necessary, as this aim at covering a broad case of application.

Usage

To run the LAMP stack in this template, you'll need to install Packer and create a DigitalOcean personal access token and set it to the DIGITALOCEAN_TOKEN environment variable. Running packer build marketplace-image.json without any other modifications will create a build Droplet configured with LAMP, clean and verify it, then power it down and snapshot it.

To start adapting this template for your own image, you can customize some variables in marketplace-image.json:

  • apt_packages lists the APT packages to install on the build Droplet.
  • image_name defines the name of the resulting snapshot, which by default is marketplace-snapshot- with a UNIX timestamp appended.

You can also modify these variables at runtime by using the -var flag.

Please see the RStudio Server 1-Click Scripts to see an example of Packer usage.

A successful run would look like this output:

pacha@pop-os:~/github/marketplace-partners$ packer build marketplace-image.json
digitalocean output will be in this color.

==> digitalocean: Creating temporary ssh key for droplet...
==> digitalocean: Creating droplet...
==> digitalocean: Waiting for droplet to become active...
==> digitalocean: Using ssh communicator to connect: 165.227.211.66
==> digitalocean: Waiting for SSH to become available...
==> digitalocean: Connected to SSH!
==> digitalocean: Provisioning with shell script: /tmp/packer-shell581341144
    digitalocean: .............................................................
    digitalocean: status: done
==> digitalocean: Uploading files/etc/ => /etc/
==> digitalocean: Uploading files/var/ => /var/
==> digitalocean: Provisioning with shell script: /tmp/packer-shell079619818
    digitalocean:
    digitalocean: WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

    ...

    digitalocean: The following NEW packages will be installed:
    digitalocean:   linux-headers-5.4.0-66 linux-headers-5.4.0-66-generic

    digitalocean: The following packages will be upgraded:
    digitalocean:   accountsservice alsa-ucm-conf apport apt apt-utils base-files bind9-dnsutils

    ... MANY MORE LINES OMITTED HERE ...
    
    digitalocean: Distribution: Ubuntu
    digitalocean: Version: 20.04
    digitalocean:
    digitalocean: [PASS] Supported Operating System Detected: Ubuntu
    digitalocean: [PASS] Supported Release Detected: 20.04
    digitalocean: [PASS] Cloud-init is installed.
    digitalocean: [PASS] Firewall service (ufw) is active
    digitalocean:
    digitalocean: Updating apt package database to check for security updates, this may take a minute...
    digitalocean:
    digitalocean: [PASS] There are no pending security updates for this image.
    digitalocean:
    digitalocean:
    digitalocean: Checking for log files in /var/log
    digitalocean:
    digitalocean: [WARN] un-cleared log file, /var/log/auth.log found
    digitalocean: [WARN] un-cleared log file, /var/log/ufw.log found
    digitalocean:
    digitalocean:
    digitalocean: Checking all user-created accounts...
    digitalocean:
    digitalocean:
    digitalocean: Checking the root account...
    digitalocean: [PASS] User root has no password set.
    digitalocean: [ OK ] User root has no SSH keys present
    digitalocean: [PASS] root's Bash History appears to have been cleared
    digitalocean: [PASS] DigitalOcean Monitoring agent was not found
    digitalocean: [PASS] MongoDB is not installed
    digitalocean:
    digitalocean: ---------------------------------------------------------------------------------------------------
    digitalocean: Scan Complete.
    digitalocean: Some non-critical tests failed.  Please review these items.
    digitalocean: ---------------------------------------------------------------------------------------------------
    digitalocean: 8 Tests PASSED
    digitalocean: 2 WARNINGS
    digitalocean: 0 Tests FAILED
    digitalocean: ---------------------------------------------------------------------------------------------------
    digitalocean: 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
    digitalocean:
==> digitalocean: Gracefully shutting down droplet...
==> digitalocean: Creating snapshot: lemp-20-04-snapshot-1615212919
==> digitalocean: Waiting for snapshot to complete...
==> digitalocean: Destroying droplet...
==> digitalocean: Deleting temporary ssh key...
Build 'digitalocean' finished.

See that this output has two acceptable warnings, but something like having ufw disabled or present SSH keys means we couldn't accept the image.

Configuration Details

By using Packer's DigitalOcean Builder to integrate with the DigitalOcean API, this template fully automates Marketplace image creation.

This template uses Packer's file provisioner to upload complete directories to the Droplet. The contents of files/var/ will be uploaded to /var/. Likewise, the contents of files/etc/ will be uploaded to /etc/. One important thing to note about the file provisioner, from Packer's docs:

The destination directory must already exist. If you need to create it, use a shell provisioner just prior to the file provisioner in order to create the directory. If the destination directory does not exist, the file provisioner may succeed, but it will have undefined results.

This template also uses Packer's shell provisioner to run scripts from the /scripts directory and install APT packages using an inline task.

Learn more about using Packer in the official Packer documentation.

Other Examples

We also use Packer to build some of the Marketplace 1-Click Apps that DigitalOcean maintains. You can see the source code for these scripts in this repo.

Update your App Image via API

The Vendor API makes it possible to update existing droplet 1-click apps programmatically. You can use this to ensure your listing features the most recently released version by tying it into your existing CI/CD pipeline to push an update to DigitalOcean.

Not all listing information can be updated via the API. For any changes outside the parameters of this request, you will still need to visit the Vendor Portal.

To update your app via the API, send a PATCH request to https://api.digitalocean.com/api/v1/vendor-portal/apps/<app_id>/versions/

App ID can be obtained from your app’s listing in Vendor Portal, via the URL. An invalid app ID will return a 404 Not Found error.

Apps in ‘pending’ or ‘in review’ state cannot be updated. Attempting to update an app in one of these states will return a 400 Bad Request error.

An authorization header with a bearer token is required to make the request. See API documentation for more information on how to obtain this token.

Request

Authorizations: bearer_auth (write)
Request Body schema: application/json

Parameters:

imageId
required
integer
ID of the image to use for your app. The image must be a snapshot already uploaded to your DigitalOcean account, under the team you use to access the vendor portal. In addition to Packer, snapshots can be created via the API through droplet actions. For additional information about manipulating snapshots via the API, view the API documentation for snapshots.

reasonForUpdate
string
A brief description of the changes made which necessitate this update.

version
string
The version to mark this update as.

osVersion
string
The version of the operating system your app runs on. A null value will not overwrite an existing value, but a blank string will.

softwareIncluded
Array of Software (see below)
Software types and versions included with your app. A null value will not overwrite an existing value, but an empty array will.

Software:

name
string
Name of this software. A null value will not overwrite an existing value, but a blank string will.

version
string
Version of this software in use by your app. A null value will not overwrite an existing value, but a blank string will.

releaseNotes
string
Any release notes to include alongside this software in your app’s listing. A null value will not overwrite an existing value, but a blank string will.

website
string
The website for this software, for further information. A null value will not overwrite an existing value, but a blank string will.

licenseType
string
The type of license this software uses. A null value will not overwrite an existing value, but a blank string will.

licenseLink
string
A link to details of the license, if applicable. A null value will not overwrite an existing value, but a blank string will.

Example request:

curl -X PATCH \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer $DIGITALOCEAN_API_TOKEN" \
 -d '{
    "reasonForUpdate": "example", 
    "version": "3", 
    "imageId": 413639,
    "softwareIncluded": [
        {
            "name": "Ubuntu Linux",
            "version": "22.04"
        }
        ]
    }' \
    https://api.digitalocean.com/api/v1/vendor-portal/apps/$APP_ID/versions/$VERSION_ID

Responses

200 - success

Returns app data in response.

Example response body:

{
    "appId": "60089fc6d333037bffa70d9b",
    "name": "Example App ",
    "version": 4,
    "type": "droplet",
      ...
    "status":
        {
        "value":"pending",
        "lastUpdated":1692302119556,
        "modifiedBy":"administrator",
        "reason":"example"
        },
    "emergencyContacts": 
        [
          ...
        ],
    "customData":
        {
        "version": "3",
        "osVersion": "Ubuntu 20.04",
        "description": "app desc",
        "summary": "app summary",
        "imageLabel": "sample-20-04",
        "imageId": 417346,
        "imageName": "Sample on Ubuntu 20.04",
        "imageDescription": "Sample 3 on Ubuntu 20.04",
        "reasonForUpdate": "Sample",
           ...
        }
}

400 - Bad Request

  • Image ID was missing from request, or
  • App in request was not a droplet 1-click, or
  • Attempted an update on an app in pending or in-review status

403 - Unauthorized

  • Authentication token was invalid, or
  • App or image does not belong to requestor’s team

404 - Not Found

  • App ID was not found or is invalid

Automating with Packer

If you are using Packer, you can add a set of post-processor actions to automatically submit your new image to update your app, via the manifest and shell-local post-processors, such as:

post-processors {     
    post-processor "manifest" {       
        output = "manifest.json"      
        strip_path = true     
    }     

    post-processor "shell-local" {        
        inline = [ "sh mp-submit.sh" ]     
    }   
}

where mp-submit.sh is

#!/bin/bash

IMG_ID=$(jq '.builds[-1].artifact_id | split(":")[1] | tonumber' manifest.json)

curl -X PATCH -H "Content-Type: application/json" -H "Authorization: Bearer ${DIGITALOCEAN_API_TOKEN}" -d "{\"reasonForUpdate\": \"new version\", \"version\": \"${APP_VERSION}\", \"imageId\": ${IMG_ID}}" https://api.digitalocean.com/api/v1/vendor-portal/apps/${APP_ID}/versions/${APP_VERSION}

You will need to set env variables DIGITALOCEAN_API_TOKEN, APP_VERSION, and APP_ID in your terminal to use this script. It uses jq to parse the manifest Packer creates for the snapshot ID, then uses cURL to submit it to the API endpoint.

Supported Operating Systems

To maintain compatibility with Marketplace tools and processes, we support a limited number of Linux distributions and releases for Marketplace images. These options provide either deb- or rpm-based packaging and will have security patches and updates for a reasonable time period.

We currently support the following OSes:

  • Debian 9 (stretch)
  • Debian 10 (buster)
  • Ubuntu 24.04 (LTS)
  • Ubuntu 22.04 (LTS)
  • Ubuntu 20.04 (LTS)
  • Ubuntu 18.04 (LTS)
  • Ubuntu 16.04 (LTS)
  • CentOS 7.x
  • CentOS 8.x
  • CentOS Stream 8
  • CentOS Stream 9
  • AlmaLinux 8.x
  • AlmaLinux 9.x
  • Rocky Linux 8.x
  • Rocky Linux 9.x

All supported operating systems are available as base images to build on in the DigitalOcean cloud.

Software Prerequisites

The following software packages are necessary for the initial configuration of new Droplets and to ensure connectivity:

  • cloud-init 0.76 or higher (0.79 or higher recommended)
  • openssh-server (SFTP-enabled configuration recommended)

All of these packages are provided by default in the default DigitalOcean base images.

Image Configuration

Running Commands on First Boot

You can often pre-load much of what your image will need in your build system, but some setup (like setting database passwords or configuration that needs the Droplet's assigned IP address) will need to be run for each new Droplet created from your image.

You can create scripts that run on first boot using cloud-init. Droplets will attempt to run any scripts located in the /var/lib/cloud/scripts/per-instance directory when they're first created. Scripts in that directory are run in alphanumerical order, so we recommend using a number as the beginning of the file names (e.g. 01-example-script.sh).

Make sure you can run the script from the command line successfully and that it has execute permissions.

Running Commands on First Login

Some of your image setup may require information that you can't get automatically, like the domain name to use for a service. You may also need to run interactive third-party scripts, like LetsEncrypt's Certbot.

To run a script on the user's first login, we recommend adding a line to the root .bashrc file that runs the script and adding a line to the script that removes the line from the root .bashrc file.

More specifically, at the end of the script you want to run on first login, add the following line. For consistency, we recommend putting first login scripts in the /opt/your_company_name directory. Make sure the script has execute permissions.

cp -f /etc/skel/.bashrc /root/.bashrc

Then add a line to the end of /root/.bashrc that runs your script by specifying the full path to the script.

When the user first logs in, the system runs .bashrc, which will automatically run your script. The last line of the script overwrites the root .bashrc with the default .bashrc from the /etc/skel directory so the call to run your script no longer exists. Using this method, your script only runs once the first time the user logs in, but the file remains in the filesystem if they need to re-run or reference it later.

Recommendations

  • Use the smallest suitable disk size.

We don't support decreasing the size of a Droplet's disk because it poses data integrity issues. Building your image using the smallest disk size appropriate for your use case lets your users choose from the widest variety of Droplet plans.

  • Do not enable unnecessary DigitalOcean features on your build Droplet.

By not enabling features like monitoring, IPv6, or private networking when you create your build Droplet, you retain more of your distribution's standard configuration, meaning you'll need to do less cleanup before you create the final image.

  • Install software updates from the distribution's repositories before creating your final image.

This secures the system and can save your users time when they create new Droplets from your image.

  • Use official package repositories or well-maintained third-party repositories whenever possible. Packages installed through other means may not provide a mechanism for applying timely security updates.

For official distribution packages, we recommend maintaining the mirrors.digitalocean.com mirrors, which are direct mirrors of the distribution's package archive. These mirrors are provided by default and provide faster downloads because the mirrors are stored within our infrastructure.

  • If you need to provide a password to your user, consider configuring it so that it is randomly generated at boot time and explain to users via your Getting Started instructions how to access the password. Here's an example of how you can generate a high quality, 12 character password on a Linux Droplet, and store it in a file on the Droplet.
gpg --gen-random --armor 2 12 > /root/.secrets.txt
  • Add a message of the day (MOTD), which is text displayed when a user logs into their Droplet. We recommend writing an MOTD which introduces your image's features and points users to its documentation.

You can add an MOTD to your image by creating a text file in /etc/update-motd.d. Naming the file beginning with 99, like 99-image-readme, will display the MOTD as the last text the user sees before the login prompt.

Contributing

We'd love to have your contribution to this project! You can find more details here.

Caveats

Avoid building architecture specific components into your 1-Click App, as your App may be run by DigitalOcean customers across a variety of operating systems and underlying hypervisors. You should use generic machine architecture to ensure consistent use across all infrastructure.

For example, avoid building ruby gems with native extensions as the underlying machine architecture may use flags that don't exist across all hypervisors.

marketplace-partners's People

Contributors

adesokanayo avatar akshaybengani789 avatar alexeigutium avatar bradford-hamilton avatar caquillo07 avatar centminmod avatar countingtoten avatar crashenx avatar dmitry-a-l avatar eskombro avatar githubsaturn avatar goksan avatar gouthamve avatar gunnaraasen avatar hazel-nut avatar jgannondo avatar jvalleroy avatar lkhn avatar mbeyt avatar paulanunda avatar peterdavehello avatar qrkourier avatar quinneckart avatar rijkvanzanten avatar ryanpq avatar scott avatar scottcrawford03 avatar sorokinaveronika avatar wadenick avatar xymka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marketplace-partners's Issues

When CentOS detects updates are available, do not FAIL if the updates are unrelated to security

Run yum list-security --security or equivalent when script running on CentOS reports that there are updates available to make sure that they are not security updates. Only FAIL when they are security updates and then list which updates were indeed security updates so that the Vendor knows which ones to address.

This is an example of the FAIL state the script will throw when running on CentOS when there are packages that need updating:
[FAIL] There are 25 updates available for this image that have not been installed.

packer.io built droplet FAILED img_check.sh

With packer.io built droplet snapshot images, packer will insert it's own SSH key during the build but automatically remove it after the build is complete.

But I am running img_check.sh at end of packer.io build so the packer SSH key is still detected. Is this okay for submission ? As it only picks up packer's SSH key prior to packer cleaning up after itself and auto removing that SSH key.

    digitalocean: Checking the root account...
    digitalocean: [PASS] User root has no password set.
    digitalocean: [FAIL] User root has a populated authorized_keys file in /root/.ssh/authorized_keys
    digitalocean: File Contents:
    digitalocean: ssh-rsa AAAAB3Nza*****
    digitalocean: --------------

and at end of packer run where that temp SSH key is deleted

    digitalocean: ---------------------------------------------------------------------------------------------------
    digitalocean: Some critical tests failed.  These items must be resolved and this scan re-run before you submit your image to the marketplace.
    digitalocean:
    digitalocean:
    digitalocean:
    digitalocean: Fri Mar 22 01:43:11 UTC 2019
==> digitalocean: Gracefully shutting down droplet...
==> digitalocean: Creating snapshot: centos7-packer-snapshot-1553217043
==> digitalocean: Waiting for snapshot to complete...
==> digitalocean: Destroying droplet...
==> digitalocean: Deleting temporary ssh key...
Build 'digitalocean' finished.

img_check.sh: Ignore the file /var/log/cpanel-install.log

When we install cPanel on a server, we automatically place a log of the installation process at /var/log/cpanel-install.log. This file is then used later on by our customers or our support staff to troubleshoot problems. Currently, img_check.sh flags this file, and emits a warning. Our customer base and support staff have come to expect this file here. Can you please modify img_check.sh to ignore /var/log/cpanel-install.log so that it no longer returns a warning and exits with a 0 status (assuming all other tests pass, of course).

Thank you!

img_check.sh: Ubuntu ufw check is not correct

On my instance at least, when I run the command

ufw status | sed -e "s/^Status:\ //"

...it returns much more than a single word!

active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 8333/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) 8333/tcp (v6) ALLOW Anywhere (v6)

...and so the == check fails here:

function checkFirewall {
if [[ $OS == "Ubuntu" ]]; then
fw="ufw"
ufwa=$(ufw status | sed -e "s/^Status:\ //")
if [[ $ufwa == "active" ]]; then

Intrusion attempts during image build cause non-empty logs

It is possible that the Droplet is attacked between the invocation of the DigitalOcean Marketplace cleanup.sh which truncates the logs and img_check.sh scripts which checks the logs, resulting in img_check.sh warning about non-empty logs due to logged intrusion attempts, and thus failing the Packer build.

Or at least I assume that is what was happening in my case, see below. I could not otherwise explain the sudden appearance of firewall related log entries after the log had been cleared.

Stopping UFW isn't an option as then img_check.sh complains. Stopping UFW logging only prevents some logging, not all. Stopping rsyslog didn't help either.

My solution was to apply a DigitalOcean firewall to the Droplet created by Packer that allowed SSH only from my IP address, thereby preventing the unwanted communication attempts from reaching the VM and thus being logged.

Automating this is non-trivial as the Packer DigitalOcean builder doesn't support enabling a DO firewall on the Droplet, nor does Packer expose the Droplet ID to the template. In theory one can use the cloud-init query instance_id command in a shell provisioner to write the Droplet ID to a file, then download it using a file provisioner and then use a shell-local provisioner to execute doctl compute firewall create to create the firewall, and then delete the firewall at the end. However, Packer doesn't have the notion of steps to always run and so the teardown of the firewall will not happen if any of the prior build steps fail, and running shell-local commands assumes the host has doctl installed and configured with the right DO API token, and brittle assumptions about which command syntax will work on the host have to be made (is it Linux, is it Windows?).

If you have any advice on how to avoid this issue that would be most appreciated. Alternatively, extending the DigitalOcean Packer builder to be able to add a firewall to the created Droplet limiting SSH to "my ip" (perhaps via a Packer user variable) would help work around this problem.

Here is an example of the problem that I encountered:

img_check.sh warnings:

    digitalocean: [WARN] un-cleared log file, /var/log/auth.log found
    digitalocean: [WARN] un-cleared log file, /var/log/kern.log found
    digitalocean: [WARN] un-cleared log file, /var/log/ufw.log found

Actual log file contents at the time:

    digitalocean: /var/log/alternatives.log
    digitalocean: /var/log/apt
    digitalocean: /var/log/auth.log
    digitalocean: Feb  1 20:33:02 packer-vm-name sshd[2570]: error: Could not load host key: /etc/ssh/ssh_host_rsa_key
    digitalocean: Feb  1 20:33:02 packer-vm-name sshd[2570]: error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key
    digitalocean: Feb  1 20:33:02 packer-vm-name sshd[2570]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
    digitalocean: Feb  1 20:33:02 packer-vm-name sshd[2570]: fatal: No supported key exchange algorithms [preauth]
    digitalocean: Feb  1 20:33:16 packer-vm-name sshd[2575]: error: Could not load host key: /etc/ssh/ssh_host_rsa_key
    digitalocean: Feb  1 20:33:16 packer-vm-name sshd[2575]: error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key
    digitalocean: Feb  1 20:33:16 packer-vm-name sshd[2575]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
    digitalocean: Feb  1 20:33:17 packer-vm-name sshd[2575]: fatal: No supported key exchange algorithms [preauth]
    digitalocean: /var/log/btmp
    digitalocean: /var/log/cloud-init-output.log
    digitalocean: /var/log/dist-upgrade
    digitalocean: /var/log/dpkg.log
    digitalocean: /var/log/journal
    digitalocean: /var/log/kern.log
    digitalocean: Feb  1 20:33:02 packer-vm-name kernel: [   72.894358] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=45.134.179.15 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=40724 PROTO=TCP SPT=42847 DPT=3400 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:33:24 packer-vm-name kernel: [   95.091120] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=89.248.168.41 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=36109 PROTO=TCP SPT=47977 DPT=1677 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:13 packer-vm-name kernel: [  144.845855] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=103.72.8.7 DST=188.166.18.107 LEN=44 TOS=0x00 PREC=0x00 TTL=243 ID=45136 PROTO=TCP SPT=58355 DPT=3395 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:32 packer-vm-name kernel: [  163.622002] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=117.148.157.48 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=237 ID=27459 PROTO=TCP SPT=53965 DPT=1433 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:19 packer-vm-name kernel: [  210.565897] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=93.174.95.110 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=61464 PROTO=TCP SPT=47917 DPT=7394 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:51 packer-vm-name kernel: [  242.250986] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=185.39.10.124 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=11142 PROTO=TCP SPT=49649 DPT=17625 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: /var/log/landscape
    digitalocean: /var/log/lastlog
    digitalocean: /var/log/lxd
    digitalocean: /var/log/syslog
    digitalocean: Feb  1 20:33:02 packer-vm-name kernel: [   72.894358] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=45.134.179.15 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=40724 PROTO=TCP SPT=42847 DPT=3400 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:32:41 packer-vm-name systemd-resolved[664]: message repeated 2 times: [ Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.]
    digitalocean: Feb  1 20:33:24 packer-vm-name kernel: [   95.091120] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=89.248.168.41 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=36109 PROTO=TCP SPT=47977 DPT=1677 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:13 packer-vm-name kernel: [  144.845855] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=103.72.8.7 DST=188.166.18.107 LEN=44 TOS=0x00 PREC=0x00 TTL=243 ID=45136 PROTO=TCP SPT=58355 DPT=3395 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:32 packer-vm-name kernel: [  163.622002] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=117.148.157.48 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=237 ID=27459 PROTO=TCP SPT=53965 DPT=1433 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:19 packer-vm-name kernel: [  210.565897] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=93.174.95.110 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=61464 PROTO=TCP SPT=47917 DPT=7394 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:51 packer-vm-name kernel: [  242.250986] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=185.39.10.124 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=11142 PROTO=TCP SPT=49649 DPT=17625 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: /var/log/tallylog
    digitalocean: /var/log/ufw.log
    digitalocean: Feb  1 20:33:02 packer-vm-name kernel: [   72.894358] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=45.134.179.15 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=40724 PROTO=TCP SPT=42847 DPT=3400 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:33:24 packer-vm-name kernel: [   95.091120] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:8a:7d:08:00 SRC=89.248.168.41 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=36109 PROTO=TCP SPT=47977 DPT=1677 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:13 packer-vm-name kernel: [  144.845855] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=103.72.8.7 DST=188.166.18.107 LEN=44 TOS=0x00 PREC=0x00 TTL=243 ID=45136 PROTO=TCP SPT=58355 DPT=3395 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:34:32 packer-vm-name kernel: [  163.622002] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=117.148.157.48 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=237 ID=27459 PROTO=TCP SPT=53965 DPT=1433 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:19 packer-vm-name kernel: [  210.565897] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=93.174.95.110 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=61464 PROTO=TCP SPT=47917 DPT=7394 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: Feb  1 20:35:51 packer-vm-name kernel: [  242.250986] [UFW BLOCK] IN=eth0 OUT= MAC=6a:1f:6d:9b:3d:41:f4:a7:39:d7:82:7d:08:00 SRC=185.39.10.124 DST=188.166.18.107 LEN=40 TOS=0x00 PREC=0x00 TTL=251 ID=11142 PROTO=TCP SPT=49649 DPT=17625 WINDOW=1024 RES=0x00 SYN URGP=0
    digitalocean: /var/log/wtmp

Supported OS: FreeBSD

As FreeBSD is now supported on DO, it makes sense that one should be able to create such an appliance for the marketplace.

ufw check fails on Ubuntu 20.04

When the img_check.sh script is run on a Ubuntu 20.04 based Droplet this ufw error appears:

main: line 340: ufw: command not found

User root has a password set on their account

I've run the script that's meant to clean up all keys, passwords, history, etc. multiple times. However, I still get the error User root has a password set on their account when running the validation. I've checked /etc/shadow and there's no password in there.

centos 7 /etc/shadow user password check

On centos 7.6 64bit for img_check.sh check for users with passwords set at /etc/shadow both nginx and memcached user for my Centmin Mod LEMP stack installs is marked as a FAILED check but I have not set any passwords on those ?

egrep 'root|nginx|memcached|mysql' /etc/shadow
root:*:16176:0:99999:7:::
nginx:!!:17961:0:99999:7:::
mysql:!!:17961::::::
memcached:!!:17961:0:99999:7:::
Checking all user-created accounts...

Checking user: nginx...
[FAIL] User nginx has a password set on their account.
[ OK ] User nginx does not have an .ssh directory

Checking user: memcached...
[FAIL] User memcached has a password set on their account.
[ OK ] User memcached does not have a directory in /home


Checking the root account...
[PASS] User root has no password set.
[ OK ] User root has no SSH keys present
[PASS] root's Bash History appears to have been cleared
[PASS] DigitalOcean Monitoring agent was not found

bash -x img_check.sh output excerpts

+ for usr in '$SHADOW'
+ IFS=:
+ read -r -a u
+ [[ nginx == \n\g\i\n\x ]]
+ [[ !! == \! ]]
+ [[ !! == \* ]]
+ echo -en '\e[41m[FAIL]\e[0m User nginx has a password set on their account.\n'
[FAIL] User nginx has a password set on their account.
+ (( FAIL++ ))
+ STATUS=2
+ for usr in '$SHADOW'
+ IFS=:
+ read -r -a u
+ [[ memcached == \m\e\m\c\a\c\h\e\d ]]
+ [[ !! == \! ]]
+ [[ !! == \* ]]
+ echo -en '\e[41m[FAIL]\e[0m User memcached has a password set on their account.\n'
[FAIL] User memcached has a password set on their account.
+ (( FAIL++ ))
+ STATUS=2

seems img_check.sh is looking for ! while centos 7 for user accounts which are locked without password set show up as !! instead https://unix.stackexchange.com/a/252019/26581

Both "!" and "!!" being present in the password field mean an account is locked.
As it can be read in the following document, "!!" in an account entry in shadow means the account of an user has been created, but not yet given a password. Until being given an initial password by a sysadmin, it is locked by default.

This maybe true on Red Hat systems, but not necessarily elsewhere - on Ubuntu or Arch Linux, a newly-created account with no password still has only !, not !!

so you may need a separate check for redhat/centos for no password set = !! while ubuntu and non-redhat/centos for no password set = ! ?

or just change line

from

if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "*" ]]; then

to

if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then

then img_check.sh run would end up as

Checking all user-created accounts...

Checking user: nginx...
[PASS] User nginx has no password set.
[ OK ] User nginx does not have an .ssh directory

Checking user: memcached...
[PASS] User memcached has no password set.
[ OK ] User memcached does not have a directory in /home


Checking the root account...
[PASS] User root has no password set.
[ OK ] User root has no SSH keys present
[PASS] root's Bash History appears to have been cleared
[PASS] DigitalOcean Monitoring agent was not found

Script throws an error when apt-check does not exist

./img_check.sh: line 299: [[: ./img_check.sh: line 298: /usr/lib/update-notifier/apt-check: No such file or directory: syntax error: operand expected (error token is "./img_check.sh: line 298: /usr/lib/update-notifier/apt-check: No such file or directory")

Add examples of how to use DigitalOcean Droplet Metadata service to configure initial passwords for webapps

We have a Vendor that uses Droplet Metadata to generate a unique password for the webapp in their 1-Click, using a call like this:

curl http://169.254.169.254/metadata/v1/id -w "\n"

Could we create an example for some common frameworks so that Vendors can more easily take the same approach?

This method for password generation within a webapp would be more secure than defaults like admin/admin.

Testing the images

Hello!

I made a snapshot using packer, but how I'm supposed to test it? I mean, everything worked fine, the snapshot was created, I can create a droplet from the snapshot and I can confirm all scripts were run just fine (at build time).

But it seems that the scripts on /var/lib/cloud/scripts did not run (I'm setting up some instance-related configs there) and MOTD doesn't appear on SSH login.

Am I missing something? How can I test those boot scripts?

img_check.sh updates for CSF Firewall

The img_check.sh script seems to only look for firewalld on CentOS systems and not other firewalls ? I use CentOS with CSF Firewall which is a wrapper for iptables for my Centmin Mod LEMP stack

so firewalld check

systemctl status firewalld
● firewalld.service
   Loaded: masked (/dev/null; bad)
   Active: inactive (dead)

echo $?
3

and if you add a csf firewall check

systemctl status csf
● csf.service - ConfigServer Firewall & Security - csf
   Loaded: loaded (/usr/lib/systemd/system/csf.service; enabled; vendor preset: disabled)
   Active: active (exited) since Wed 2019-03-06 10:04:15 UTC; 46min ago
  Process: 2858 ExecStart=/usr/sbin/csf --initup (code=exited, status=0/SUCCESS)
 Main PID: 2858 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/csf.service

Mar 06 10:04:13 hostname systemd[1]: Starting ConfigServer Firewall & Security - csf...
Mar 06 10:04:15 hostname systemd[1]: Started ConfigServer Firewall & Security - csf.
Mar 06 10:04:15 hostname csf[2858]: (restoring ipsets) (restoring iptables) (restoring ip6tables)

echo $?
0

so maybe modify img_check.sh

from

    if [[ $OS == "Ubuntu" ]]; then
      fw="ufw"
      service ufw status >/dev/null 2>&1
    elif [[ $OS == "CentOS Linux" ]]; then
      fw="firewalld"
      systemctl status firewalld >/dev/null 2>&1
    fi

to

    if [[ $OS == "Ubuntu" ]]; then
      fw="ufw"
      service ufw status >/dev/null 2>&1
    elif [[ $OS == "CentOS Linux" ]]; then
      if [ -f /usr/lib/systemd/system/csf.service ]; then
        fw="csf"
        systemctl status $fw >/dev/null 2>&1
      else
        fw="firewalld"
        systemctl status $fw >/dev/null 2>&1
      fi
    fi
./img_check.sh    
DigitalOcean Marketplace Image Validation Tool v. 0.1
Checking local system for Marketplace compatibility...

Distribution: CentOS Linux
Version: 7

[PASS] Supported Operating System Detected: CentOS Linux
[PASS] Supported Release Detected: 7
[PASS] Cloud-init is installed.
[PASS] Firewall service (csf) is active

Checking for available updates with yum, this may take a minute...

[PASS] There are no pending security updates for this image.

Checking for log files in /var/log

[WARN] un-cleared log file, /var/log/lfd.log found

guess need to clean the CSF Firewall login failure daemon log too

[WARN] un-cleared log file, /var/log/lfd.log found

though the log only re-populates as it's watching directory log files so even after

find /var/log -mtime -1 -type f -exec truncate -s 0 {} \;

csf firewall will re-populate lfd.log

cat /var/log/lfd.log
Mar  6 11:00:16 hostname lfd[3451]: /var/log/messages has been reset. Reopening log file
Mar  6 11:00:16 hostname lfd[3451]: Watching /var/log/messages...

so everytime img_check.sh will get that warning though so maybe need to exclude the file from img_check.sh ?

so I'd need to setup on first login one time script to re-run

find /var/log -mtime -1 -type f -exec truncate -s 0 {} \;

to exclude lfd.log maybe ?

    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
        echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n"
        ((WARN++))
        if [[ $STATUS != 2 ]]; then
          
            STATUS=1
        fi
      elif [[ "${f}" != '/var/log/lfd.log' && "$( cat "${f}" | wc -c)" -gt 50 ]]; then
        echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found\n"
        ((WARN++))
        if [[ $STATUS != 2 ]]; then
          
            STATUS=1
        fi
      fi
    done

edit: In addition to that, another false assumption I see is for CentOS detection, your img_check.sh script assumes both CentOS 6 and CentOS 7 use firewalld, while firewalld is only use in CentOS 7 and not CentOS 6 which just uses iptables directly.

Count of security updates does not match the number of updates that are listed

Based on there being 16 updates available, I would have expected a list of 16 packages but there is a much smaller number here.

[PASS] Supported Operating System Detected: Ubuntu
[PASS] Supported Release Detected: 18.04
[PASS] Cloud-init is installed.
[WARN] No firewall is configured. Ensure ufw is installed and configured

Updating apt package database to check for security updates, this may take a minute...

[FAIL] There are 16 security updates available for this image that have not been installed.
Here is a list of the security updates that are not installed:
bzip2
libbz2-1.0
libglib2.0-0
libglib2.0-data
tzdata
python3-problem-report
python3-apport
apport

Infinit copying on run cleanup script

When i ran this script his never stop. When i cancel execution via Ctrl+C i saw:

root@prisma-cms:~/tmp# ./cleanup.sh 
Hit:1 http://security.ubuntu.com/ubuntu bionic-security InRelease
Hit:2 https://deb.nodesource.com/node_10.x bionic InRelease                                                                 
Hit:3 http://mirrors.digitalocean.com/ubuntu bionic InRelease                                                               
Hit:4 https://apt.dockerproject.org/repo ubuntu-xenial InRelease         
Get:5 http://mirrors.digitalocean.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:6 http://mirrors.digitalocean.com/ubuntu bionic-backports InRelease [74.6 kB]
Fetched 163 kB in 1s (148 kB/s)                                
Reading package lists... Done
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
^C37216798+0 records in
37216798+0 records out
19055000576 bytes (19 GB, 18 GiB) copied, 118.86 s, 160 MB/s

root@prisma-cms:~/tmp# 

UPD: snapshot site increased too: http://joxi.ru/LmGyqplHwZZZPA

What is meant by "Submit your final image"?

Hi! We've been going through the Marketplace submission process and got a little bit confused at some points.

We have completed steps 1-3 and have the repo ready here:
https://github.com/meilisearch/meilisearch-digital-ocean

The 4th and final step goes as follows:

Submit your final image to the Marketplace team for review.

It doesn't link anywhere. Do you mean submit here?
https://marketplace.digitalocean.com/vendors

I entered the form on /vendors and got this mail back:

Thanks for your interest in the DigitalOcean Marketplace!

You can find more information on getting started with your listing in the DigitalOcean Marketplace, here. Once you’ve had a chance to review, please feel free to schedule 30 minutes for us to discuss and confirm the next steps.

I look forward to speaking.

This was a bit confusing as well because I couldn't tell if this call is optional or a required step towards entering the marketplace. Is it "feel free" as in do it? 😄

In any case I've got a call set up for next week so I expect that'll clear up any misunderstandings we might have had.

Log files sometimes don't get cleared by cleanup script

I'm trying to package an application for DO using packer.

After creating my image I do run the (top-level) cleanup script provided in this repository and the (top-level) image check script.

Doing so I am running in intermittent failures, having the image check complain about un-cleared log files (either /var/log/ufw.log or /var/log/auth.log or sometimes both of them). I would assume that 75% of the build succeed, the rest will fail for the above reason.

I have a hard time understanding how these log files cannot be caught here:

find /var/log -mtime -1 -type f -exec truncate -s 0 {} \;
rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-????????
and it's even stranger that manually adding:

rm -f /var/log/auth.log /var/log/ufw.log

does not resolve the issue either.

Is there some race condition going on here? I also added set -eo pipefail to the cleanup script so I can be sure that it does not error on something unexpected here before trying to delete the log files.

This is the order of scripts in my Packer config

    {
      "type": "shell",
      "environment_vars": [
        "OFFEN_VERSION={{user `offen_version`}}"
      ],
      "scripts": [
        "scripts/10-install",
        "scripts/20-configure_service",
        "scripts/30-configure_firewall",
        "scripts/40-add_firstrun",
        "scripts/90-cleanup",
        "scripts/99-img_check"
      ]
    }

and for the sake of completeness this is the error output:

    digitalocean: Checking for log files in /var/log                                                                                                                                                        
    digitalocean:                                                                                                                                                                                           
    digitalocean: [WARN] un-cleared log file, /var/log/ufw.log found       

img_check.sh succeeds even when security updates are available

This issue causes apt-get update in cleanup.sh and img_check.sh to fail, yet the scripts continue with the end result that the exit code can be zero and the following output is shown:

    do: [PASS] There are no pending security updates for this image.
    do:
    do:
    do: Checking for log files in /var/log
    do:
    do:
    do:
    do: Checking all user-created accounts...
    do:
    do:
    do: Checking the root account...
    do: [PASS] User root has no password set.
    do: [ OK ] User root has no SSH keys present
    do: [PASS] root's Bash History appears to have been cleared
    do: [PASS] DigitalOcean Monitoring agent was not found
    do: [PASS] MongoDB is not installed
    do:
    do: ---------------------------------------------------------------------------------------------------
    do: Scan Complete.
    do: All Tests Passed!
    do: ---------------------------------------------------------------------------------------------------
    do: 8 Tests PASSED
    do: 0 WARNINGS
    do: 0 Tests FAILED
    do: ---------------------------------------------------------------------------------------------------
    do: 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).

Yet submission to the vendor portal was rejected with:

As part of that review process, when I ran the img_check.sh(https://raw.githubusercontent.com/digitalocean/marketplace-partners/master/scripts/img_check.sh) script it mentioned that the image needs a security update:

[FAIL] There are 1 security updates available for this image that have not been installed.
Here is a list of the security updates that are not installed:
apport

Add support for suppressing warnings on img_check.sh

Currently the img_check.sh prints out all success, warnings and errors that it found on a given image.

We should add an optional flag to suppress warnings from the output in order to reduce noise, and not providing this flag defaults to the current behavior.

first boot /opt/vendorname/script.sh interactive works on droplet rebuilds ?

In instructions at https://github.com/digitalocean/marketplace-partners/blob/master/marketplace_docs/build-an-image.md#running-commands-or-interactive-scripts-on-first-login it says to setup /opt/vendorname/script.sh for interactive first login setups and that on creating a new droplet with the snapshot image, it will trigger the script. However, is the same true for when you rebuild a droplet with the same snapshot image ? I setup my snapshot image built with packer.io with CentOS 7 with the following at /opt/centminmod

ls -lah /opt/centminmod/
total 20K
drwxr-xr-x. 2 root root   89 Mar 11 08:06 .
drwxr-xr-x. 5 root root   49 Mar 11 08:15 ..
-rwxr-xr-x. 1 root root 9.7K Mar 11 08:06 first-login.sh
-rw-r--r--. 1 root root  380 Mar 11 08:06 memcache-admin-login.txt
-rw-r--r--. 1 root root  335 Mar 11 08:06 php-info-password.txt

where /opt/centminmod/first-login.sh would be triggered by entry in /root/.bashrc which will prompt for email, hostname and regenerate memcached, and mysql passwords and at the end override the modified /root/.bashrc with default

cp -f /etc/skel/.bashrc /root/.bashrc

however, if i rebuild an already launched droplet with the snapshot image, the first-login.sh prompt doesn't fully happen but some of the script does get run to regenerate the memcache and php passwords

the packer provisioners section is setup as

  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "mkdir -p /opt/centminmod"
      ]
    },
    {
      "type": "file",
      "source": "scripts/first-login.sh",
      "destination": "/opt/centminmod/"
    },
    {
      "type": "shell",
      "inline": [
        "chmod +x /opt/centminmod/first-login.sh",
        "echo '/opt/centminmod/first-login.sh' >> /root/.bashrc"
      ]
    },
    {
      "type": "shell",
      "environment_vars": [
        "INSTALL_ELREPO={{user `install_elrepo`}}",
        "INSTALL_BBR={{user `install_bbr`}}",
        "INSTALL_DOCKER={{user `install_docker`}}",
        "INSTALL_REDIS={{user `install_redis`}}",
        "INSTALL_AUDITD={{user `install_auditd`}}",
        "INSTALL_BROTLI={{user `enable_brotli`}}",
        "INSTALL_PHPPGO={{user `enable_phppgo`}}",
        "INSTALL_LOGROTATEZSTD={{user `enable_logrotate_zstd`}}",
        "INSTALL_PHPFPMSYSTEMD={{user `enable_phpfpm_systemd`}}"
      ],
      "scripts": [
        "scripts/cmm-install.sh"
      ],
      "remote_folder": "/home",
      "remote_file": "script_1.sh"
    }
  ]

List the security updates that are missing when security updates are missing

Today the script throws a FAIL when security updates are missing, but it does not tell you which updates are missing.

Being able to see what updates are missing would be useful for us as we could communicate exactly what updates were missing to the seller/vendor.

This issue may be a good one to pair with #15 since they are both related to security updates. // @ryanpq

Need help to get OpenY Drupal distribution in DigitalOcean marketplace

Hi, dear team
We'd like to create our own marketplace app for the customers to start with.
It was not easy to find how this could be done.
From what I already understood we should create a droplet. make a snapshot from it and then somehow to send for approval.
The last steps is not clear. Looks like the only way is to ask.
Could you provide me a details of how to push our distro to DigitalOcean MarketPlace?

Details
github repo https://github.com/ymcatwincities/openy
Sandbox http://sandbox.openymca.org

Basically sandbox is a thing that will be automatically installed on DigitalOcean Droplet to be used in MarketPlace. We'll take care about all underlying cleanups and scripts.

Make one recommended image build process (remove manual)

This issue is to request we make one recommended method to build an image. I was going to submit a PR to just remove the "manual" method but the readme (https://github.com/digitalocean/marketplace-partners/blob/master/README.md) states "some" parts in the manual process are required for the automated process. I was not sure what parts in the manual process are required for the automated process.

Thus, this issue is to suggest we move to one recommended process, anticipating that vendors will need to make updates to their image. Therefore, we should create a pre-req section to the automated build process that includes items needed from the manual process. Then remove references to the manual process. Going forward we then only reference one build process.

MOTD not displaying by default (ubuntu 20.04)

It looks like PrintMotd no is the default on the ubuntu 20.04 images so my motd isn't displaying. Is there another way to display helpful information to users on first login or should I just include the correct sshd_config in my packer build?

Provide instructions on recommended method to use Packer [template]

Reading through:
https://github.com/digitalocean/marketplace-partners/blob/master/marketplace_docs/build-an-image-fabric.md

I was unable to find instructions on the recommended method to use Packer in a DO one-click build process. While we have https://github.com/digitalocean/marketplace-partners/tree/master/marketplace_docs/templates/Packer it would be nice to link the Packer instructions with the Fabric documentation with our recommendations on how to set up a DO one-click build pipeline.

Packer build images failing DigitalOcean droplet snapshot creation with 504 gateway timeout errors ?

I've built out my Centmin Mod LEMP stack's DO droplet snapshot image building routines using Packer https://github.com/centminmod/centminmod-digitalocean-marketplace/tree/master/packer#using-build-imagesh-script for preparing images for DO Vendor Market Place submission but my last few runs of Packer had ended in errors at snapshot image creation stage in Packer with DO API returning 504 gateway timeout errors ? It seems to be a Cloudflare 504 returned error I suspect it's protecting the DO API and something isn't configured correctly and Cloudflare isn't getting a response back from DO API ?

Cloudflare reports 504 error with Ray ID: 4ccedc82ca4f9336

My commands to build a Centmin Mod LEMP stack image were

cd /root/tools/centminmod-digitalocean-marketplace/packer
git stash
git pull
./build-image-with-kernel-ml.sh 44955XXX s-1vcpu-1gb

which builds a CentOS 7 image via Packer using Droplet size = s-1vcpu-1gb which defaults to using Linux 5.0.x mainline kernel using a previously updated golden CentOS 7 snapshot image id = 44955XXX

starting output

packer validate packer-centos7-basic.json
Template validated successfully.

packer inspect packer-centos7-basic.json
Optional variables and their defaults:

  do_image               = centos-7-x64
  do_image_name          = centos7-packer-snapshot-php72-{{timestamp}}
  do_region              = sfo2
  do_size                = c-2
  do_tags                = cmm
  do_token               = {{env `TOKEN`}}
  enable_argon           = n
  enable_brotli          = n
  enable_dualcerts       = n
  enable_logrotate_zstd  = n
  enable_phpfpm_systemd  = n
  enable_phppgo          = n
  install_auditd         = n
  install_bbr            = n
  install_customcurl     = n
  install_docker         = n
  install_elrepo         = n
  install_go             = n
  install_mariadbtenfour = n
  install_mariadbtentwo  = n
  install_mongodb        = n
  install_newergit       = n
  install_nodejs         = n
  install_redis          = n

Builders:

  digitalocean

Provisioners:

  shell
  file
  file
  shell
  shell

Note: If your build names contain user variables or template
functions such as 'timestamp', these are processed at build time,
and therefore only show in their raw form here.

time TMPDIR=/home/packertmp PACKER_LOG=1 packer build -var do_image=44955XXX -var do_size=s-1vcpu-1gb -var do_region=sfo2 -var enable_argon=y -var 'install_elrepo=y' -var 'install_bbr=y' -var 'install_redis=y' -var 'enable_phpfpm_systemd=y' packer-centos7-basic.json
digitalocean output will be in this color.

==> digitalocean: Creating temporary ssh key for droplet...
==> digitalocean: Creating droplet...
==> digitalocean: Waiting for droplet to become active...
==> digitalocean: Using ssh communicator to connect: 167.99.xxx.xxx
==> digitalocean: Waiting for SSH to become available...
==> digitalocean: Connected to SSH!
==> digitalocean: Provisioning with shell script: /home/packertmp/packer-shell655352819
==> digitalocean: Uploading scripts/first-login.sh => /opt/centminmod/
1 items:  42.29 KiB / 42.29 KiB [=====================================================================================================================================================================================================================] 0s
==> digitalocean: Uploading scripts/01-setup-first-login.sh => /var/lib/cloud/scripts/per-instance/
1 items:  1.30 KiB / 1.30 KiB [=======================================================================================================================================================================================================================] 0s
==> digitalocean: Provisioning with shell script: /home/packertmp/packer-shell072918681
==> digitalocean: Provisioning with shell script: scripts/cmm-install.sh
    digitalocean: LETSENCRYPT_DETECT='y'
    digitalocean: SWITCH_PHPFPM_SYSTEMD='y'
    digitalocean: NGINX_VIDEO='y'
    digitalocean: PHPFINFO='y'
    digitalocean: PHP_LZFOUR='y'
    digitalocean: PHP_LZF='y'
    digitalocean: PHP_ARGON='y'
    digitalocean:
    digitalocean:
    digitalocean: hostname: packer-5cc15a71-b807-6db8-9b11-e82628f10fc1
    digitalocean:
    digitalocean: Architecture:          x86_64
    digitalocean: CPU op-mode(s):        32-bit, 64-bit
    digitalocean: Byte Order:            Little Endian
    digitalocean: CPU(s):                1
    digitalocean: On-line CPU(s) list:   0
    digitalocean: Thread(s) per core:    1
    digitalocean: Core(s) per socket:    1
    digitalocean: Socket(s):             1
    digitalocean: NUMA node(s):          1
    digitalocean: Vendor ID:             GenuineIntel
    digitalocean: CPU family:            6
    digitalocean: Model:                 63
    digitalocean: Model name:            Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz
    digitalocean: Stepping:              2
    digitalocean: CPU MHz:               1799.998
    digitalocean: BogoMIPS:              3599.99
    digitalocean: Virtualization:        VT-x
    digitalocean: Hypervisor vendor:     KVM
    digitalocean: Virtualization type:   full
    digitalocean: L1d cache:             32K
    digitalocean: L1i cache:             32K
    digitalocean: L2 cache:              256K
    digitalocean: L3 cache:              30720K
    digitalocean: NUMA node0 CPU(s):     0
    digitalocean: Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt

however when it comes time for Packer to shutdown the build droplet to create the resulting snapshot, it fails with DO API returning 504 gateway timeout

==> digitalocean: Gracefully shutting down droplet...
==> digitalocean: Creating snapshot: centos7-packer-snapshot-php72-1556175473
==> digitalocean: Waiting for snapshot to complete...
==> digitalocean: Error waiting for snapshot: GET https://api.digitalocean.com/v2/droplets/1414XXXXXX/actions/672746207: 504 <!DOCTYPE html>
==> digitalocean: <html>
==> digitalocean: <head>
==> digitalocean:   <title>DigitalOcean - Something went wrong!</title>
==> digitalocean:   <style type="text/css" >body{background-color:#fff;margin:0;padding:0;font-family:"Proxima Nova",Helvetica,sans-serif}h1{font-size:40px;color:#4b4b4b;font-weight:700;text-align:center;margin-top:0;margin-bottom:0;padding:0 10px}.sub-copy a{color:#474747;border-bottom:1px dotted #474747;text-decoration:none}.sub-copy{font-size:24px;font-weight:400;color:#3686be;line-height:1.5;max-width:800px;margin:0 auto;text-align:center;padding:15px 10px 0}.sammy{display:block;margin:0 auto;max-width:100%;position:relative;left:-50px}.header{background:#3686be;padding:40px}.header a,.header img{margin:0 auto;display:block}.waves{width:100%;height:100px;background-image:url(data:image/png;charset=binary;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAEsCAMAAACxJAyMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBxE1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzNBQTYyQTUzQzE4MTFFNEFBQjlFQjJBQ0U4QjgwREIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzNBQTYyQTYzQzE4MTFFNEFBQjlFQjJBQ0U4QjgwREIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFMzdBMDkxNjNCODQxMUU0QUFCOUVCMkFDRThCODBEQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3M0FBNjJBNDNDMTgxMUU0QUFCOUVCMkFDRThCODBEQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pj9AJwgAAAGPUExURf///zaGvjiHv2ymz9/s9f7//zeGvoq42cnf7ou52m+o0Pb5/EGNwrLQ5rPR5/3+/leayWGgzG2n0Pz9/vL3+16ey83h7zmIv3mu1DyKwLTS5/P4++vz+Xet04Gz1kqSxfn8/a3O5F2dylaZyFGWx8Ha62CfzN7r9NXm8U2UxUOOwpnB3jqIv9Dj8D6Lwe/2+sTb7GWizaPH4bfU6Pr8/cLa65bA3a7O5ez0+Ya22ICz1pfA3Y272pW/3T2KwGyn0JG9293r9IO110iRxGSizUWPw06VxsXc7Pb6/ESPw4e32Gmlz6zN5DuJwK/P5aXJ4lOYx1SYyHKq0anL4+30+dPk8crf7nCp0U+VxrbT6Mbd7UKNwlucytzq9Gqlz5nC3mOhzW6o0Hyw1UyTxaHH4drp85O+3Ojx+JG93J/F4Ony+PX5/MPb7ECMwb3X6l2ey/n7/ff6/PH2+n+y1bXS5+71+p3E38DZ64W119jn8ufx977Y6ubw93Or0lKXx8je7Y262qTI4lmbydfn8vj7/RBgL8EAAAITSURBVHja7NfVchRAFEXRZjQTd0+ICyHE3XB3d3d3d/hwXnmBiowF1vqDXbfqdHXY8I8IQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIEbJuQxZ3HK2pqYhGe2rKux6tw5BdV68vTD3suz8efvf0/amJ9q2FXZH1EFI8kpwaHAp/9fNWyfbORP6GRC7OlMbiYZmeDy90JPIvZMvSvdqisFLTJccb8iikbuRKbVtYpQdjhZG8CDmbGi4Ka3Py5ucch2y+PBoL6RA/fSaRs5BNLx43hfS51HooFyH9qYKqkGZ37hZnOaRz7kc8ZMLQ7cXshTx5HQuZ05ysy0ZIZOeRjyHDegtDQUVmJ6qyvTlkR/xDecYe7pZz1SGLyhp3Z2JoZ988C9k2Xprmq2xMpn9ol3mViaVEmiISPQN98ZBDsdS+tVdcaCmdDjnXNlZYt5adrZirrQp54tXByoZVRXTMd1eH/LK3e+bGyv6pBwbON4X8FCt5+z2ynHWKzr/sLQv5rangRDLa/4eChmOVXw8PVof1o2jbl8Zvk/tn6z9Fo9fq61tTk6ONe941BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ge/BBgAc8GKsbXnyeIAAAAASUVORK5CYII=);background-size:100px 100px;background-repeat:repeat-x;opacity:1}.cf-error-details{max-width:800px;margin:40px auto 0;text-align:center}.cf-error-details p{max-width:600px;margin:20px auto 0}.cf-error-details ul{list-style-type:none;line-height:20px}</style>
==> digitalocean: 
==> digitalocean: 
==> digitalocean: </head>
==> digitalocean: 
==> digitalocean: <body>
==> digitalocean:   <div class="header">
==> digitalocean:     <a href="https://www.digitalocean.com"><img src="data:image/png; charset=binary;base64,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"></a>
==> digitalocean:   </div>
==> digitalocean:   <div class="waves"></div>
==> digitalocean:   <div class="oops-copy">
==> digitalocean:     <h1>Looks like something went wrong...</h1>
==> digitalocean:     <p class="sub-copy">If this keeps happening, check out <a href="https://status.digitalocean.com/">status.digitalocean.com</a>.</p>
==> digitalocean:     <div class="cf-error-details cf-error-504">
==> digitalocean:   <h1>Gateway time-out</h1>
==> digitalocean:   <p>The web server reported a gateway time-out error.</p>
==> digitalocean:   <ul class="cferror_details">
==> digitalocean:     <li>Ray ID: 4ccedc82ca4f9336</li>
==> digitalocean:     <li>Your IP address: 159.65.xxx.xxx</li>
==> digitalocean:     <li>Error reference number: 504</li>
==> digitalocean:     <li>Cloudflare Location: San Jose</li>
==> digitalocean:   </ul>
==> digitalocean: </div>
==> digitalocean: 
==> digitalocean:   </div>
==> digitalocean: </body>
==> digitalocean: </html>
==> digitalocean: Destroying droplet...
==> digitalocean: Deleting temporary ssh key...
Build 'digitalocean' errored: Error waiting for snapshot: GET https://api.digitalocean.com/v2/droplets/1414XXXXXX/actions/672746207: 504 <!DOCTYPE html>

Part of the Packer build script routine is I inspect the droplet's IP geo data and looks like Cloudflare reported issue with Ray ID: 4ccedc82ca4f9336

==> digitalocean:   <div class="waves"></div>
==> digitalocean:   <div class="oops-copy">
==> digitalocean:     <h1>Looks like something went wrong...</h1>
==> digitalocean:     <p class="sub-copy">If this keeps happening, check out <a href="https://status.digitalocean.com/">status.digitalocean.com</a>.</p>
==> digitalocean:     <div class="cf-error-details cf-error-504">
==> digitalocean:   <h1>Gateway time-out</h1>
==> digitalocean:   <p>The web server reported a gateway time-out error.</p>
==> digitalocean:   <ul class="cferror_details">
==> digitalocean:     <li>Ray ID: 4ccedc82ca4f9336</li>
==> digitalocean:     <li>Your IP address: 159.65.xxx.xxx</li>
==> digitalocean:     <li>Error reference number: 504</li>
==> digitalocean:     <li>Cloudflare Location: San Jose</li>
==> digitalocean:   </ul>
==> digitalocean: </div>

I see status entry at https://status.digitalocean.com/incidents/m9b2g31t4g9z for 9hrs ago with DO API issues, but my issue is happening around 25 mins ago. Is it an DO API issue and/or a Cloudflare configuration issue for protected DO API ?

cleanup.sh error: "dd: writing to '/zerofile': No space left on device"

When launching cleanup.sh on an Ubuntu 18.04 with Apache/PHP/MariaDB installed, I get this:

root@chamilo-1-11-10:~# ./cleanup.sh 
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:2 http://mirrors.digitalocean.com/ubuntu bionic InRelease [242 kB]
Hit:3 http://mirrors.digitalocean.com/ubuntu bionic-updates InRelease
Hit:4 http://mirrors.digitalocean.com/ubuntu bionic-backports InRelease
Fetched 331 kB in 0s (676 kB/s)                   
Reading package lists... Done
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following package was automatically installed and is no longer required:
  grub-pc-bin
Use 'apt autoremove' to remove it.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  grub-pc-bin
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 2987 kB disk space will be freed.
(Reading database ... 69617 files and directories currently installed.)
Removing grub-pc-bin (2.02-2ubuntu8.13) ...
Reading package lists... Done
Building dependency tree       
Reading state information... Done

dd: writing to '/zerofile': No space left on device
42100865+0 records in
42100864+0 records out
21555642368 bytes (22 GB, 20 GiB) copied, 122.474 s, 176 MB/s
root@chamilo-1-11-10:~# df
Filesystem      Size  Used Avail Use% Mounted on
udev            481M     0  481M   0% /dev
tmpfs            99M  592K   98M   1% /run
/dev/vda1        25G  4.0G   21G  17% /
tmpfs           493M     0  493M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           493M     0  493M   0% /sys/fs/cgroup
/dev/vda15      105M  3.6M  101M   4% /boot/efi
tmpfs            99M     0   99M   0% /run/user/0
root@chamilo-1-11-10:~#

I'm not sure wether this is important at all, but I didn't find information to tell me what it's trying to do (not sure this has to do with grub-pc-bin or not).

Print the contents of the authorized_keys file if it is populated

When running the script on a live Droplet, a FAIL for the authorized_keys check may be due to the fact that there's a key in there for the current user (i.e. they ssh'd in using that key). That key should be printed out if it exists so the user running the script can quickly tell if old keys are in that file, or it's simply the key they used to login to the Droplet.

Change the way that security updates are communicated to the user

Via @ryanpq

Our script will report if any security updates are needed. The motd will report all needed updates. The script uses the same utility that Ubuntu's unattended-updates tool uses to automate security updates. I think the best course of action to resolve any confusion would be to add the second check to our script so it can report X updates can be installed, X security updates are required

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.