File: README.md
Sandstorm
Sandstorm is a self-hostable web productivity suite. It's implemented as a security-hardened web app package manager. Sandstorm makes it easy to run your own server.
Use Sandstorm to install apps to create documents,
spreadsheets, blogs,
git repos, task lists, and
more as easily as you'd install apps on your
phone.
Sandstorm is open source and can be installed on any x86-64 Linux
system.
- Read more at: https://sandstorm.io/
- Try the demo: https://demo.sandstorm.io/
- Documentation available at: https://docs.sandstorm.io/
Installing
See installation instructions in the Sandstorm documentation.
Using Sandstorm
See the overview in the Sandstorm documentation.
How It Works
See how it works and security practices in the Sandstorm documentation.
How to Package Apps
See the developer hub in the Sandstorm documentation.
Contribute
Want to help? Check out CONTRIBUTING.md. Also see our community page or get on our discussion group and let us know!
File: acme-dns-01-sandcats/README.md
ACME.js plugin for Sandcats.io
This allows you to issue Let's Encrypt certificates against your Sandcats.io subdomain.
This code is intended to be used inside the Sandstorm server.
File: docs/administering/active-directory.md
This document explains how to integrate with Microsoft Active Directory (also known as AD). This
allows all users, or specific users within your Windows domain, to log into a Sandstorm server.
AD & Sandstorm: Overview
Sandstorm can rely on AD to authenticate users.
Active Directory exists as part of a cloud product called Windows Azure as well as a software
product called Windows Server. Sandstorm supports both products.
Sandstorm can be configured to use single sign-on in a configuration where AD has full control over
the login form, allowing you to enjoy AD's support for multi-factor authentication, Windows
credentials login, and a consistent sign-in experience for all apps within your organization. As a
security benefit, the Sandstorm software never sees the user's passwords. This relies on Sandstorm's
support for SAML 2.0.
This document provides textual advice as well as a great deal of screenshots to allow you to proceed
with confidence. If you have questions, please open an issue on GitHub. We want to help you
successfully set up Sandstorm!
Note that you can also set up Sandstorm to integrate with Active Directory using LDAP bind to
authenticate users. We recommend Active Directory Federation Services or Microsoft Azure AD Single
Sign-On instead. Both of these products use SAML for authentication. If you must use LDAP bind for
authentication instead, see the general documentation about
LDAP.
Windows Azure Active Directory
Summary: Once you have created a directory, you must add a new application from the gallery,
configure Sandstorm as a custom app, then enable Microsoft Azure AD Single Sign-On. This
process will involve Azure AD creating a SAML provider entry point URL and a custom SAML
certificate. Once you have done this, you can use Active Directory to choose which users in your
domain are allowed to use Sandstorm.
Here is a screenshot tour, using example.sandcats.io as an example Sandstorm server.
These instructions use the Classic Azure Active Directory portal found at
manage.windowsazure.com. If you are using the new portal at
portal.azure.com, please click on "classic portal" or browse to manage.windowsazure.com in order to
follow these instructions.
Go to: manage.windowsazure.com
Click "Active Directory" in the sidebar.
Choose the directory you wish to use to sign into Sandstorm.
Click "Applications" in the top bar.
Choose "Add" from the bottom bar (NOT "+ New").
Choose "Add an application from the gallery"
Choose "custom" from the sidebar. Choose "Add an unlisted application my organization is using".
- If this option is not displayed: Make sure you are using the classic portal. At the time of
writing, Microsoft is still working on adding this option to the new portal. This option may
require upgrading to Azure AD Premium.
- If this option is not displayed: Make sure you are using the classic portal. At the time of
Enter name: "Sandstorm". Click the checkmark in the lower-right.
Choose "Configure single sign-on"
Choose "Microsoft Azure AD Single Sign-On". Click the "next" arrow.
Now, visit your Sandstorm server and begin configuring SAML login. In the Sandstorm SAML config, adjust the "Entity ID" to be the full URL to your Sandstorm server, including the leading "https://", which you will also use as the Azure AD "Identifier". Azure AD requires that the entity ID be a full URL, not a hostname. You will also need to copy the Sandstorm server's Service URL to your clipboard.
Return to the Microsoft Azure AD page in your web browser. For "Identifier", enter the Sandstorm server's URL. (Example: "https://example.sandcats.io") For "Reply URL", enter the Sandstorm server's Service URL from the Sandstorm SAML config. (Example: "https://example.sandcats.io/_saml/validate/default"). Click the "next" arrow.
Click "Download Certificate (Base 64 - most common)".
Open the certificate file in a text editor (such as Notepad).
Copy/paste the contents of the file into Sandstorm's SAML login configuration under "SAML cert for above provider:".
Back in the Azure AD configuration, copy the line titled "Single Sign-On Service URL". In the Sandstorm config, paste this under "SAML provider entry point URL:".
In the Azure AD config, check the box: "Confirm that you have configured single sign-on as
described above." Click the "next" arrow.Enter your email address for service alerts from Microsoft. Click
the checkbox to complete configuration.Click "Assign accounts".
Click: "Users and Groups", then "All Users". Click the check-mark to request Sandstorm access for
all users.The system will ask you if you are sure. Click "Yes" to confirm.
Congratulations! You have enabled Sandstorm for all the users in your Microsoft Azure Active Directory service.
Windows Server Active Directory
Summary: Once you have created a directory, you must use Active Directory Federation Services to
add a new Relying Party, namely the Sandstorm web application. Each Sandstorm server publishes
federation metadata information at a URL available within the SAML configuration page. You must
configure a rule that sends the user email address to Sandstorm, as well as a rule that declares
email addresses are the persistent identifier. You must also export the custom SAML certificate to
Sandstorm. Once you have done this, you can use Active Directory to choose which users in your
domain are allowed to use Sandstorm.
To connect to Active Directory via SAML, you must enable Active Directory Federation Services (AD
FS). We will assume you have already done this. We also assume that your users' web browsers can
reach the the Sandstorm server as well as the AD server. With SAML, all communication between the
Service Provider (Sandstorm) and the Identity Provider (AD) is through the browser. The only
server-to-server communication happens during setup, where AD FS fetches a configuration XML file
from Sandstorm. If desired, the admin can avoid this server-to-server communication be by
downloading the XML from Sandstorm and then uploading it to AD separately.
Note that AD FS requires that your Sandstorm server supports HTTPS with a valid certificate. You can
use a private CA for this, but setting up a private CA is beyond the scope of this document.
Here is a screenshot tour, using example.sandcats.io as an example Sandstorm server.
Part 1: Configure AD FS
Open the AD FS management UI.
In the left sidebar, browse to: "Trust Relationships > Relying Party Trusts". In the right sidebar, click: "Add Relying Party Trust...".
You will see the "Add Relying Party Trust Wizard." Click "Start."
At this time, open the Sandstorm SAML configuration interface in a new browser tab. Take note of
the Sandstorm service provider metadata URL. This is typically of the form:
https://example.sandcats.io/_saml/config/defaultBack in the "Add Relying Party Trust Wizard," choose the radio button for: "Import data about the
relying party published online or on a local network". Under "Federation metadata address (host
name or URL)", enter the address of Sandstorm server's service URL. This is typically of the form:
https://example.sandcats.io/_saml/config/default . Then, click Next.- If your Sandstorm server does not support HTTPS, AD FS will complain at this point. Do NOT try to work around this by downloading the metadata and feeding it to AD FS manually. If you do that, AD FS may appear to accept the metadata, but it will leave all the endpoints unconfigured, because AD FS will not accept a non-HTTPS endpoint.
Choose a display name (for example, the server's hostname like example.sandcats.io) and notes if
desired, then click "Next".Choose whether to configure multi-factor authentication and click "Next". (Configuring
multi-factor is beyond the scope of this document.)Choose "Permit all users to access this relying party" and click "Next".
Review your choices and click "Next".
Check the box for: "Open the Edit Claim Rules dialog for this relying party trust when the wizard closes".
Then, click Close.The "Edit Claim Rules" dialog appears. Click "Add Rule..."
Under "Claim rule template", choose: "Send LDAP Attributes as Claims". Then click "Next."
Under "Claim rule name", enter: "Send e-mail address" (or any name you want). Use "Active
Directory" as the attribute store. Configure the LDAP Attribute as E-Mail Addresses and the
Outgoing Claim Type as E-Mail Address. Then click "Finish."Click "Add Rule...".
Under "Claim rule template", choose: "Transform an Incoming Claim". Click "Next."
Under "Claim rule name", enter: "Assign name ID from e-mail address" (or any name you want). Configure the
Incoming claim type as "E-Mail Address" and set the Outgoing claim type to "Name ID." Set the Outgoing
format to "Persistent Identifier." Choose to "Pass through all claim values." Finally, click "Finish."- NOTE: This differs from many other services. Do NOT choose "Email" here. You MUST choose
"Persistent Identifier". This is because Sandstorm allows an advanced administrator to choose
a different user attribute to use as the primary identifier. For example, if your system has a
notion of numeric user IDs that never change, you could use that as the Name ID instead. This
way, you could change a user's e-mail address in the future without requiring that they
transfer all of their Sandstorm data to a new account. However, most administrators choose to
use e-mail addresses as the primary identifier, accepting that this means that e-mail
addresses can never change.
- NOTE: This differs from many other services. Do NOT choose "Email" here. You MUST choose
Click "OK" to finish editing claim rules.
Part 2: Extract your certificate
Open the AD FS management UI. In the left sidebar, browse to: "Service > Certificates".
Click on the certificate under "Token-signing" to select it.
Click "View Certificate..." In the Certificate dialog, go to the "Details" tab.
In the "Details" tab, click "Copy to File..."
The Certificate Export Wizard appears. Click "Next".
Choose the radio button for: "Base-64 encoded X.509 (.CER)". Click "Next."
Choose where to save the certificate. Click "Next."
Review the "Completing the Certificate Export Wizard" information, then click "Finish."
Open the certificate file using a text editor, such as Notepad. You will need to copy/paste this next in the next part.
Part 3: Configure Sandstorm
Open Sandstorm's SAML login configuration.
Under "SAML provider entry point URL", enter your AD FS login entry point. This is usually
"/adfs/ls" at the host associated with your Active Directory server. For example, if your Active
Directory server is ad.example.com, the URL would be: https://ad.example.com/adfs/lsUnder "SAML cert for above provider", copy the contents of the certificate you extracted in part
2, above.For the entity ID, keep the Sandstorm default, which is your server hostname. For example,
example.sandcats.io. If you change this value, logins will not work until you resynchronize AD
FS with Sandstorm's SAML metadata.Finally, click "Save."
This concludes setting up Windows Server Active Directory with Sandstorm! If you have any questions
or need further help, please email [email protected]! We'd be honored to work with you to get
your server set up properly.
File: docs/administering/backups.md
Backups
You can manually perform backups of Sandstorm data via the web interface and/or via the command line.
In the long run, we'd like to enable automated backups as well.
To back up one individual grain
If you're the owner of a grain on Sandstorm, you can back up an individual grain by clicking the
download icon in the top bar. This will give you a ZIP file of the grain's
contents. This contains the full writable state of the app, so you can restore it to any Sandstorm
server.
If you want to get crafty, you can modify a backup to point to a different app ID, allowing you to
migrate data between apps, or use your data with an experimental app with a different app ID. To
do this:
- Make a backup of your data from the "old" app.
- With the "new" app, create a new empty grain and make a backup of it.
- Find the file called "metadata" inside the second backup, and copy it over to the first backup,
overwriting its own "metadata". Now you have a zip which Sandstorm will recognize as belonging
to the new app, even though the data came from the old app.
You can also change the contents of the backup before restoring it, by modifying the files in the
zip.
In this way, Sandstorm gives every app a fully-functional import/export system.
To back up the entire Sandstorm server
Sandstorm stores all its data in /opt/sandstorm, plus two symbolic links in /usr/local/bin, plus
a service file for systemd or sysvinit.
If you run your own Sandstorm server, you can back up the entire Sandstorm installation safely by
stopping the service:
sudo sandstorm stop
sudo service sandstorm stopand taking a filesystem snapshot of /opt/sandstorm. If your filesystem doesn't support online
snapshots you can make a quick backup by running:
cp -a /opt/sandstorm $HOME/sandstorm-snapshot-from-$(date -I)Alternatively, one can make a backup using tar.
tar -cf $HOME/sandstorm-snapshot-from-$(date -I).tar /opt/sandstormThen restart Sandstorm to end the interruption:
sudo service sandstorm startThis guide uses $(date -I), which is a way to embed the current date into a filename, in a format
such as 2005-10-30.
Note about warnings from tar: If you see errors involving socket files being ignored, you can
ignore those warnings. The tar utility might print messages like this:
/opt/sandstorm/var/sandstorm/grains/bdMmGkov6gpiSSXC9GHysy/socket: socket ignoredYou should rely on tar's exit code being 0 to know if the tar command completed successfully.
To restore a Sandstorm server backup
If you have a tar-based backup of /opt/sandstorm, the easiest way to restore it is to:
Run the install script, and allow it to configure a systemd/sysvinit service.
Stop the Sandstorm service, e.g.
sudo sandstorm stopMove the
/opt/sandstormdirectory to/opt/sandstorm.emptyCopy your backup into
/opt/sandstormStart the Sandstorm service, e.g.
sudo service sandstorm startVisit your Sandstorm server and make sure everything still works.
Remove the now-useless
/opt/sandstorm.emptydirectory.
You can also use the Docker container
documentation to run your snapshot of/opt/sandstorm. You will need to create a Docker volume with your backup of /opt/sandstorm, and
it will continue to execute until you stop the Docker container.
File: docs/administering/config-file.md
This document provides detailed technical documentation, also known as reference documentation,
on the available options within Sandstorm's configuration file, sandstorm.conf.
Overview
At Sandstorm startup,
run-bundle.c++
parses the configuration file, using the information to adjust Sandstorm startup details. Typically
this takes the form of passing the config options to the Sandstorm shell as Meteor settings, but it
includes choosing what user ID to switch to, what environment variables to set, and other startup
details.
Most Sandstorm installations use /opt/sandstorm as the main directory. In that case, you can find
sandstorm.conf in /opt/sandstorm/sandstorm.conf.
List of all sandstorm.conf settings and their effects
SERVER_USER
If Sandstorm is started as root, Sandstorm will switch to the user ID named by this configuration parameter.
On a default install, this is sandstorm. Example:
SERVER_USER=sandstormPORT
A comma-separated list of port numbers on which Sandstorm will bind, listening for inbound HTTP.
By default, 80 if that port was available; otherwise, 6080.
If Sandstorm is started as root, Sandstorm binds to this port as root, allowing it to use
low-numbered ports. The socket is passed-through to code that does not run as root.
Example:
PORT=80,6080Sandstorm treats the first PORT value differently from the other ones, which we call alternate ports.
First port. When a request reaches Sandstorm via first PORT, if the request is for a URL within
the WILDCARD_HOST pattern, then serve a response. If the request is for a URL that is not within
the WILDCARD_HOST pattern, typically a static publishing website, then also serve a response.
Alternate ports. When a request arrives and it is for a URL within the WILDCARD_HOST pattern,
Sandstorm serves a HTTP redirect to a canonicalized version of the requested URL, with the intent
of serving the request using the primary port. If the request is outside the WILDCARD_HOST pattern,
typically a static publishing website, then serve a normal response.
HTTPS_PORT
A port number for Sandstorm to bind on and listen for HTTPS. On a default install, if port 443
was available and the user chose to use Sandcats, this is 443. However, this may be set for any
Sandstorm-managed TLS configuration, including automated renewals of certificates with Let's Encrypt
with a supported DNS provider or a manually-uploaded certificate. If this config option is missing,
Sandstorm's built-in HTTPS server is disabled.
If Sandstorm is started as root, Sandstorm binds to this port as root, allowing it to use
low-numbered ports. The socket is passed-through to code that does not run as root.
Example:
HTTPS_PORT=443A HTTPS_PORT is automatically treated as the first port, in the context of "first port" vs.
"alternate ports."
SMTP_LISTEN_PORT
A port number on which Sandstorm will bind, listening for inbound email. By default, 30025; if
missing, the Sandstorm shell uses 30025. You can choose port 25 if you like.
If Sandstorm is started as root, Sandstorm binds to this port as root, allowing it to use
low-numbered ports. The socket is passed-through to code that does not run as root.
Example:
SMTP_LISTEN_PORT=25BIND_IP
The IP address on which Sandstorm will listen for HTTP (via PORT), HTTPS (via HTTPS_PORT), and SMTP
(via SMTP_LISTEN_PORT). Supports IPv4 or IPv6 addresses. Example:
BIND_IP=0.0.0.0MONGO_PORT
A port number that Sandstorm will bind to for its built-in MongoDB service. By default,
6081.
Example:
MONGO_PORT=6081BASE_URL
The URL you expect people to type into their browser address bar to reach your sandstorm server, like https://alpha.sandstorm.io or http://local.sandstorm.io:6080. It should include protocol (http:// or https://), host, and port (if non-default), but no path. Note that if you have a reverse proxy in front of your web site, BASE_URL points at the proxy, not directly at the Sandstorm server -- again, it's the URL people type into the address bar, not necessarily the physical address of the Sandstorm server itself.
Example:
BASE_URL=http://sandstorm.example.com:6080WILDCARD_HOST
This specifies a pattern of addresses all of which also end up at your Sandstorm server. Unlike BASE_URL, WILDCARD_HOST should not include a protocol, only hostname and optionally port. The hostname must have a * somewhere in it. If this * is replaced by any alphanumeric string, and the value is prefixed with the same protocol used in BASE_URL, the result should be a URL which, if entered in the browser, would resolve to your Sandstorm server. So, for example, alpha-*.sandstorm.io is the WILDCARD_HOST for Sandstorm Alpha, while *.oasis.sandstorm.io is the WILDCARD_HOST for Oasis, and *.local.sandstorm.io:6080 might be the WILDCARD_HOST for a local server. Notice that you can put the * anywhere you want in the URL, but most DNS servers only support a leading *. in a wildcard entry.
Example:
WILDCARD_HOST=*.sandstorm.example.com:6080UPDATE_CHANNEL
The path within install.sandstorm.io that Sandstorm automatically checks for downloads. The term
is borrowed from Google Chrome. By default,dev. Set it to none to disable updates. Note that at the time of writing, there is only one
channel, dev.
Example:
UPDATE_CHANNEL=devSANDCATS_BASE_DOMAIN
A hostname that is used as the API host for the built-in
sandcats dynamic DNS and free HTTPS certificates service. By default, sandcats.io
if the user chooses to use sandcats; otherwise, missing. The presence/absence of this setting
controls if Sandstorm will connect to the sandcats service. By setting it to a different hostname,
you can use a different implementation of the sandcats protocol.
Example:
SANDCATS_BASE_DOMAIN=sandcats.ioALLOW_DEMO_ACCOUNTS
A boolean (true/false or yes/no) that controls if this Sandstorm server has demo mode enabled.
By default, absent (which is the same as false).
Example:
ALLOW_DEMO_ACCOUNTS=falseALLOW_DEV_ACCOUNTS
A boolean (true/false or yes/no) that controls if this Sandstorm server allows any visitor to sign in and have
admin privileges or a user account. This feature is quite dangerous; it is enabled by default for
dev accounts (including within vagrant-spk). By default, false.
Example:
ALLOW_DEV_ACCOUNTS=falseUSE_EXPERIMENTAL_SECCOMP_FILTER
A boolean (true/false or yes/no) that controls whether to use
Sandstorm's experimental new seccomp filter (as opposed to the old one).
The new filter is stricter, and is disabled by default. Once it is
deemed sufficiently mature the new filter will become the default.
LOG_SECCOMP_VIOLATIONS
A boolean (true/false or yes/no) that controls whether violations of the
seccomp filter should be logged to the kernel's message log, when using
the new experimental seccomp filter. Defaults to false.
ALLOW_LEGACY_RELAXED_CSP
A boolean (true/false or yes/no) that controls whether to allow apps to
load client-side scripts from third-party servers. Several apps are not
yet compatible with the new Content Security Policy, so the legacy one is
currently enabled by default. Once app support is deemed sufficiently
adequate, the new CSP will become the default.
IS_TESTING
Used rarely. A boolean (true/false or yes/no) that adjusts internal settings for Sandstorm's
integration test suite.
DDP_DEFAULT_CONNECTION_URL
Used rarely. Alternate URL for Meteor DDP. Useful in the unusual case that you use a CDN for
your BASE_URL.
HIDE_TROUBLESHOOTING
Deprecated. A boolean (true/false or yes/no) that hides the "Troubleshooting" link on
the login areas within Sandstorm. Works at present, but may be removed in the future. Use the
Personalization section of the admin panel to configure this and other related options.
WILDCARD_PARENT_URL
Deprecated. Historic alternative to WILDCARD_HOST.
MAIL_URL
Deprecated. URL for outbound SMTP. Configure SMTP using the admin area within Sandstorm
instead.
File: docs/administering/demo.md
Demo mode
This page documents some features of the Sandstorm demo mode, which is the mode in which demo.sandstorm.io runs. The code for demo mode is in the main Sandstorm repository but usually is not enabled.
Purpose of demo mode
The main purpose of the demo mode is to let people learn more about the Sandstorm platform by using a Sandstorm instance without having to think about registering for an account.
A secondary purpose, the code for which is not yet fully implemented, is to enable people to try out Sandstorm apps without having to think about registering for an account or "installing" the app.
Data deletion
A demo user and their data is deleted one hour after the user is created. To learn about how, read the code implementing the demo.
At the time of writing, the period of data deletion is not configurable.
Enabling demo mode
Demo mode is mainly intended to run on demo.sandstorm.io, since the purpose is to show you what Sandstorm looks like before you've installed it. That said, you can enable it on your own installation.
To enable demo mode, add the following line to sandstorm.conf:
ALLOW_DEMO_ACCOUNTS=trueApp demos
When a Sandstorm instance allows demo accounts, a visitor can surf to:
/appdemo/:appId
(where appId is the key ID of an app installed on that server).
At that URL, we show a screen to the visitor indicating that their data will vanish in a hour. When they click on the "Try appName" button, they find themselves in a working instance of the app.
This hinges on the app named by appId being installed on the server.
Your app's ID can be found near the top of the package definition file (sandstorm-pkgdef.capnp), where it will be defined something like this:
const pkgdef :Spk.PackageDefinition = (
id = "nqmcqs9spcdpmqyuxemf0tsgwn8awfvswc58wgk375g4u25xv6yh",To find the ID of an already-built .spk package, run spk unpack on it; it will print the ID to the console. For apps on the Sandstorm app list, you can also look at the data-app-id attribute on the "install" button.
File: docs/administering/email.md
Email in Sandstorm
This tutorial will show you how to setup your personal sandstorm instance with support for e-mail.
First, a quick rundown of how email works in sandstorm. Sandstorm is
running an SMTP server on port 30025 that will accept email of the
form publicId@hostname. publicId is randomly generated for every
grain that handles e-mail, and hostname is extracted from theBASE_URL parameter in sandstorm.conf (which is initially created by
the installer script). Outgoing e-mail is sent through an external
SMTP server, controllable from the Admin settings -> Email configuration page.
(Note that the MAIL_URL parameter in sandstorm.conf has been
deprecated.) When sending e-mails, the only valid "From" addresses are
the grain's generated publicId@hostname address, or the verified
email from the user's account (e.g. the e-mail address obtained via
e.g. Google or Github or email login). The interfaces for sending/receiving e-mails
are available in
hack-session.capnp.
Outgoing SMTP
Apps can send email out to the world, subject to rate limiting. To enable this feature, you must
configure an SMTP relay in the Email configuration page of the Admin panel. The SMTP server needs
to accept e-mails with the SMTP envelope's bounce address set to either your grain's local address
or the "Sandstorm server's own email address" address.
If running at home or at work, you can usually use your ISP's or corporation's SMTP
server. Otherwise, Sendgrid, Mailgun, and others
provide SMTP services, some with free tiers. Note in our testing, Google Gmail is incompatible with
the Sandstorm outbound SMTP requirements: it will modify the From header and SMTP envelope to be
your personal address, rather than what the app specified. Therefore it may seem to work for the
first user, but when you add other users to your server, any emails sent by their apps will appear
to come from you!
Some cloud providers block outbound port 25, which you may experience as Sandstorm reporting
"Connection timed out." In that case, check if your outbound SMTP provider supports alternative
ports such as 587 or 2525.
sandcats.io users: Since the sandcats dynamic DNS & HTTPS service does not
support special DNS records that improve email deliverability, we recommend you configure a
Server's own email address on a domain you personally control, not your sandcats subdomain.
Then, be sure to use an SMTP provider to configure that domain and your DNS provider to configure
SPF/DKIM records.
Receiving email into Sandstorm grains
To allow Sandstorm grains to receive email, you need to do the following.
Set up DNS for a domain: Configure DNS so that other computers know how to deliver email to your server.
Configure port 25 on your server: When email messages arrive on inbound port 25, they must
reach Sandstorm. Sandstorm will then route them to any specific grain.
Aside: How to test your configuration
One great way to test inbound email is to use the Roundcube app. To do that:
Install Roundcube
from the Sandstorm app market into an account on your Sandstorm server.Click Create a mailbox from Roundcube's app details page on your server.
Click Connect to Your Address within a Roundcube grain. You should now see an inbound email
address for this Roundcube grain of the form.
Once you know Roundcube's inbound email address, use a separate email system such as Gmail to send
it an email! If this test email appears within Roundcube, you can skip the rest of these steps!
Inbound emails should appear within 5 seconds of when you send them; if they do not, click
Roundcube's Refresh button to make sure.
Set up DNS
Grains can receive inbound email, and their email adddresses are always of the form{{publicId}}@{{BASE_DOMAIN}}. {{BASE_DOMAIN}} is the domain name value component of BASE_URL
in your sandstorm.conf. {{publicId}} is a random unique ID that is assigned to this grain by
Sandstorm. Therefore, the domain in your BASE_URL needs to have a DNS configuration that enables
inbound email.
sandcats.io users: No action is required. Servers on the Internet that send you email will
connect to the IP address of the DNS A record maintained by the sandcats.io service.
Sandstorm users on your own domain: No action is usually required, since presumably your
server's BASE_URL resolves properly to your Sandstorm server. For extra standards compliance, you
can add an MX record for the domain name that you use in your BASE_URL. You can use any number
as the MX priority, for example, 10.
Configure port 25, the easy way: Sandstorm can listen on port 25
By default, Sandstorm's SMTP server runs on port 30025. You can adjust it to listen on port 25.
This is the easiest way to configure inbound email; however, note that Sandstorm's SMTP server does
not support inbound STARTTLS at this time.
Make sure nothing else is running on port 25 on this system. Then edit/opt/sandstorm/sandstorm.conf to add this new line:
SMTP_LISTEN_PORT=25Now stop & start Sandstorm.
At this point, you should be able to test inbound email to your Roundcube grain.
Configure port 25, the advanced way: Proxy SMTP
If you need to share Sandstorm's SMTP service with port 25 used by other services, or you want
inbound STARTTLS, you can configure Sandstorm's SMTP service to sit behind a reverse proxy. One way
to do accomplish this is with nginx. Add the following to your nginx.conf:
mail {
ssl_certificate /etc/keys/my-ssl.crt;
ssl_certificate_key /etc/keys/my-ssl.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers on;
server {
listen 25;
server_name sandstorm.example.com;
auth_http localhost:8008/fake-smtp-auth;
protocol smtp;
timeout 30s;
proxy on;
xclient off;
smtp_auth none;
starttls on;
}
server {
listen 465;
server_name sandstorm.example.com;
auth_http localhost:8008/fake-smtp-auth;
protocol smtp;
timeout 30s;
proxy on;
xclient off;
smtp_auth none;
ssl on;
}
}nginx requires that you provide an authentication handler for all SMTP proxies. We don't actually
need authentication because our server is only meant to receive e-mail destined for this host (it
will not relay). So, we have to set up a fake authentication handler. In the part of your nginx
config where you defined your HTTP servers (e.g. /etc/nginx/sites-available/default), add this
fake server for SMTP auth purposes:
# Fake SMTP authorizor which always accepts. Put this in your http block.
server {
listen 127.0.0.1:8008;
server_name localhost;
location /fake-smtp-auth {
add_header Auth-Server 127.0.0.1;
add_header Auth-Port 30025;
return 200;
}
}File: docs/administering/faq.md
One way to use Sandstorm is to run the software on your own server -- we call that
self-hosting. This page answers common questions from self-hosters.
How do I log in, if there's a problem with logging in via the web?
If logging into your Sandstorm server over the web isn't working, you can reset your Sandstorm's
login providers. Resetting login providers will retain all existing accounts, including account
metadata such as who is an admin.
These instructions assume you've installed Sandstorm as root, which is the default
recommendation. If not, remove the sudo from the instructions below.
Use e.g.
sshto log into the server running Sandstorm.Run this command to generate a token you can use to log in as an admin, for emergency administration.
textsudo sandstorm admin-tokenThis will print a message such as:
textGenerated new admin token. Please proceed to http://sandstorm.example.com/admin/19bc20df04838fdc03101d898be075cc02de66f2 in order to access the admin settings page and configure your login system. This token will expire in 15 min, and if you take too long, you will have to regenerate a new token with `sandstorm admin-token`.Visit the link it printed out, which gives you emergency access to the server's admin panel.
From there, configure the login providers of your choosing.
Now, log in as yourself. If you log in as the first user that ever signed into this Sandstorm instance, then you will be an admin.
Why does Sandstorm require a wildcard host?
See Why Sandstorm needs a wildcard host.
How do I change the domain name for my Sandstorm server?
If your Sandstorm server is currently online, and you want to change the domain name used to reach
it, you'll need to adjust /opt/sandstorm/sandstorm.conf and restart Sandstorm.
Before you change the domain name, read the following notes to avoid common problems.
If you're using sandcats free HTTPS, you'll need to disable Sandstorm's built-in HTTPS when you
switch to a new domain name. Sandstorm's built-in HTTPS only supports sandcats domains at the
moment. We recommend disabling HTTPS and getting Sandstorm working on your domain with just HTTP
first, to avoid confusion, and then adding HTTPS in a second step. When you're ready, you can
configure nginx or other reverse proxy tools to get HTTPS on your own domain name.Your new Sandstorm domain will need to support wildcard DNS. You should set up your
wildcard DNS record before you change Sandstorm's hostname.Changing the server hostname will temporarily disable Google and GitHub login, since those login
providers embed an assumption about your server's hostname. You will be able to re-enable the
login providers after you switch to the new Sandstorm server hostname; you can use command line
access to gain temporary admin access to the server while the login providers are disabled.
To change the domain name, edit /opt/sandstorm/sandstorm.conf. To do that, use ssh or a similar tool
to gain access to your server, and run a command such as:
sudo nano /opt/sandstorm/sandstorm.confIn this file, you should change BASE_URL to your new URL, including http:// or https:// and
any port number that you need. You should typically set WILDCARD_HOST to*.{{yourSandstormDomain}}.
The WILDCARD_HOST setting should use the same port number as the BASE_URL. If your service is on
port 80 and is a HTTP service, no port number is needed; if your service is on port 443 and is a
HTTPS service, no port number is needed. WILDCARD_HOST should not specify a protocol.
In order to disable HTTPS for sandcats, look for a line starting with HTTPS_PORT= and remove it.
Finally, save and exit your text editor (for example with Ctrl-o <ENTER> and Ctrl-x in nano).
Now restart Sandstorm to make the changes take effect. You can typically do that by running:
sudo sandstorm restartNow visit your server's admin panel to make sure that all settings look OK. Make sure to review
the login settings and test that grains launch properly. If you can't get into the admin panel, you
can generate an "admin token" on the command line by running this command.
sudo sandstorm admin-tokenWhy can't I access Sandstorm from the Internet, even though the server is running?
If your sandstorm.conf looks like this:
SERVER_USER=sandstorm
PORT=6080
MONGO_PORT=6081
BIND_IP=127.0.0.1
BASE_URL=http://mydomain.com:6080
WILDCARD_HOST=*.mydomain.com:6080
UPDATE_CHANNEL=devthen you need to change the BIND_IP value to 0.0.0.0.
(To be pedantic, this the unspecified IPv4 address. For IPv6
compatibility, you may want :: instead. We haven't tested this yet.)
What ports does Sandstorm need open?
If you have a strict firewall around the server running Sandstorm, or
you are at home and have to enable "port forwarding" on a home wifi
gateway, here is a list of the ports Sandstorm needs. This applies on
cloud providers like Amazon EC2, where the defaults allow no inbound
traffic.
Default configuration
- TCP port 6080
- TCP port 30025
Optionally
- TCP port 443
- TCP port 80
What are the minimum hardware requirements?
- Architecture: amd64 (aka x86_64)
- RAM: 1 GB
- Disk space: 5 GB
- Swap: Enabled, if possible
You can probably get away with less, but we wouldn't advise it. 2GB is vastly better than 1 GB.
Using a virtual machine from Amazon EC2, Google Compute Engine,
Linode, Digital Ocean, etc., is fine; just make sure you have a recent
Linux kernel. The latest Ubuntu LTS release is an easy and good choice of base
operating system.
Sometimes I randomly see a lot of errors across the board, while other times the same functions work fine. What's going on?
Do you have enough RAM? Linux will start randomly killing processes when it's low on RAM. Each grain
you have open (or had open in the last couple minutes) will probably consume 50MB-500MB of RAM,
depending on the app. We therefore recommend using a server with at least 2GB. If you have less that
that, see the next question.
My virtual machine doesn't have that much RAM, what can I do?
It might help to set up swap space. The following commands will set up a file on-disk to use as
swap:
dd if=/dev/zero of=/swap.img bs=1M count=1024
mkswap /swap.img
swapon /swap.img
echo /swap.img swap swap defaults 0 0 >> /etc/fstabWhy do you support only Google, GitHub, and passwordless email for login?
Using Google or Github for login results in top-notch security and
straightforward federated authentication with very little work. This
lets Sandstorm be focused on what it's good at. (We could add Twitter,
Facebook, etc. login as well, but we are worried about people
forgetting which one they used and ending up with multiple accounts.)
For email logins, we chose to avoid passwords entirely. Passwords have
a lot of problems. People choose bad passwords. People -- even smart
people -- are often fooled by well-crafted phishing attacks. And, of
course, people regularly forget their passwords. In order to deal with
these threats, we believe that any password-based login system for
Sandstorm must, at the very least, support two-factor authentication
and be backed by a human security team who can respond to
hijackings. There must also be an automated password reset mechanism
which must be well-designed and monitored to avoid
attacks. Unfortunately, we don't have these things yet. Moreover, we
don't believe that building a secure password login system is the best
way for Sandstorm to deliver something interesting to the ecosystem.
Another problem with password login is that it makes federation more
complicated. When you federate with your friend's server, how does it
authenticate you? Not by password, obviously. Perhaps by OpenID or
OAuth, but that is again a thing we would need to implement.
In short, we think these are the most secure options we can provide
right now.
A note about when and why we think security is important:
For self-hosted Sandstorm servers, we want to provide a secure experience.
For public Sandstorm servers supporting a large number of users, account security is essential.
For a development instance only accessible to
localhost, login security may not be particularly important. You can enable the dev accounts feature to create accounts for testing apps.
Federated login enables tracking, and passwordless email login enables
anyone with temporary access to an email account to hijack an account.
One way to overcome these problems is by building GPG login so you can
create an account based on your public key. You can track progress on
that effort in this
issue.
Why do I see an error when I try to launch an app, even when the Sandstorm interface works fine?
Sometimes Sandstorm seems to be working fine but can launch no apps. This typically relates to
Sandstorm's need for wildcard DNS. If you use HTTPS, you will also need wildcard HTTPS.
You can read technical details if you wish.
You might see an error screen like this:
even when the app management interface seems to work fine:
You might also have seen a warning from the Sandstorm admin settings area. An error will appear if
your configuration fails the self-test. If so, read the Javascript console. Sandstorm will log
details in your browser's Javascript console, although those details might be
minimal;
thankfully, your web browser will typically provide further details about the failed connection in
the Javascript console. Here are some hints, based on errors you might see.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource: This
usually means your WILDCARD_HOST and BASE_URL disagree about port number, or the WILDCARD_HOST and
BASE_URL disagree about your domain name.Connection refusedornet::ERR_CONNECTION_REFUSED: This can occur if your WILDCARD_HOST
specifies the wrong domain name or if the WILDCARD_HOST and BASE_URL disagree about port number.HTTPS security errorornet::ERR_INSECURE_RESPONSE: This can occur if you are using a
self-signed certificate for Sandstorm but have not set up a self-signed CA. Read our docs on
self-signed SSL for Sandstorm.
Here are some tips to fix configuration issues that can cause WILDCARD_HOST problems.
- Make sure the
WILDCARD_HOSThas valid syntax. In the Sandstorm config file (typically/opt/sandstorm/sandstorm.conf), look for theWILDCARD_HOSTconfig item. Note that this should
not have a protocol as part of it but does need a port number ifBASE_URLspecifies a
port number. A valid line might be:
WILDCARD_HOST=*.yourname.sandcats.io:6080Make sure wildcard DNS works for your chosen domain. See also our documentation on wildcard
DNS. If setting up wildcard DNS is a hassle for you, consider using our free
Sandcats dynamic DNS service for yourBASE_URLandWILDCARD_HOST.Make sure wildcard HTTPS works on your server if your server uses HTTPS. Consider using our
free Sandcats dynamic DNS and HTTPS service if you are OK choosing a subdomain of
sandcats.io as your server's name, e.g. example.sandcats.io. If you are using a self-signed
certificate, note that you must import a CA certificate into all web browsers where you want the
Sandstorm server to able to be viewed. Web browsers do not show a "OK to continue?" prompt for
IFRAMEs, and Sandstorm uses IFRAMEs. Read more in the self-signed SSL guide.
You can also read our HTTPS topic guide.
Can I customize the root page of my Sandstorm install?
You can definitely customize the root page of your Sandstorm install. You might have noticed that
Oasis has a customized front page.
This is by contrast with the default, which you can see on our older
alpha.sandstorm.io service.
This is achieved by configuring a web page to be displayed in the background behind the login dialog
(the home page when logged out). To configure this setting, visit your server's Admin panel
screen and click Personalization. You can enter a URL as the Splash URL (experimental).
For security reasons, the page must be hosted within your Sandstorm server's wildcard host
(otherwise it will be blocked by Content-Security-Policy). We suggest using a static web
publishing app like Hacker
CMS to host the
content.
This feature is experimental; in particular the style and positioning of the login box is subject to
change without notice. Please let us know if
you'd like to see it stabilize.
When creating your own page like this, we suggest using the Oasis splash URL as a starting point.
Use your browser's DOM inspector to find the IFRAME that is on the background of Oasis. Use its
CSS rules to guide your own.
Can Sandstorm use a HTTP proxy for outgoing connections?
Yes. Set the http_proxy and https_proxy environment variables in your systemd service or init
script. Right now, this can be used to install apps, but other uses of the proxy are untested. If
you discover problems with the HTTP proxy support, please file a
bug.
As background, a Sandstorm server uses Internet access to achieve tasks like:
Downloading apps to install.
Automatically updating itself.
Automatically downloading app updates.
Updating your IP address on file with the sandcats service.
If your environment requires configuring a HTTP proxy for outbound Internet connectivity, and you
are using systemd, then you can edit /etc/systemd/system/sandstorm.service to look like the
following. You will then need to run sudo systemctl daemon-reload then sudo systemctl restart sandstorm.
[Unit]
Description=Sandstorm server
After=local-fs.target remote-fs.target network.target
Requires=local-fs.target remote-fs.target network.target
[Service]
Type=forking
ExecStart=/opt/sandstorm/sandstorm start
ExecStop=/opt/sandstorm/sandstorm stop
Environment=http_proxy=http://127.0.0.1:3128/
Environment=https_proxy=http://127.0.0.1:3128/
[Install]
WantedBy=multi-user.targetIf you use sysvinit or a different init system, then make whatever similar change results in
the http_proxy and https_proxy environment variables being set.
Note that the sandcats.io dynamic DNS protocol requires the ability to send UDP packets to the
Internet, so if the system cannot do that, then its IP address will not auto-update. If your IP
address does not change frequently, this should be OK.
How do I use Sandstorm with an internal IP address?
Since Sandstorm relies on wildcard DNS, you will need to modify your sandstorm.conf
to point at a hostname that resolves to your internal IP address. If your organization cannot
provide one, you can either use our free sandcats.io DNS service & HTTPS that uses public IP
addresses, or use xip.io's free wildcard DNS for internal IP
addresses.
To use xip.io, if your Sandstorm server is at (for example) 10.0.0.2, then you should:
Open
/opt/sandstorm/sandstorm.confin your favorite text editor, for example by runningsudo nano /opt/sandstorm/sandstorm.confFind the line containing
BASE_URLand modify it to say:
BASE_URL=http://10.0.0.2.xip.io:6080Make sure the port number above corresponds to the port in your
PORT=...line.Find the line containing
WILDCARD_HOSTand modify it to say:
WILDCARD_HOST=*.10.0.0.2.xip.io:6080Make sure the port number is the same as the port number in
BASE_URL.Make sure your configuration file does not use the
HTTPS_PORTorSANDCATS_BASE_DOMAIN
settings, which refer to integrating with the sandcats.io DNS & HTTPS service. If you see them,
comment them out or remove them.
#HTTPS_PORT=443
#SANDCATS_BASE_DOMAIN=sandcats.ioSave and exit your text editor (for example with
Ctrl-oandCtrl-xin nano).Restart Sandstorm by running this command in a terminal.
sudo sandstorm restart- Visit your Sandstorm install at http://10.0.0.2.xip.io/ and make sure it is working OK.
Note that you might not have to do this! For the purpose of this question, an internal IP address is
something like 192.168.x.y or 10.x.y.z; see Wikipedia's article on private
networks. Many organizations use global IP
addresses like 18.x.y.z and rely on their organization firewall to prevent external access; in that
case, our free sandcats.io DNS service should work fine.
Keep in mind that xip.io is maintained by the kind and gracious Sam Stephenson,
not by a member of the Sandstorm team. If you want to run your own wildcard DNS service similar to
xip.io inside your own organization, you can do so by downloading
xipd which Sam generously licenses as open source software.
You can also set up your own *.sandstorm.example.com subdomain within your organization's domain.
mongod failed to start. What's going on?
If your Sandstorm server isn't working, and you find this text in /opt/sandstorm/var/log/sandstorm.log:
**mongod failed to start. Initial exit code: 100, bailing out now.then MongoDB is unable to start. Sandstorm operates an embedded MongoDB database instance to store
information like what user accounts exist and what permissions they have. Keep the following in mind
to address the issue.
Your system might not have enough free disk space. Sandstorm requires about 500 MB available space
to start successfully.You can read
/opt/sandstorm/var/log/mongo.logto find out MongoDB's true error
message. Specifically, the file will be invar/log/mongo.logunderneath wherever Sandstorm is
installed; most Sandstorm installations are at/opt/sandstorm.You might be running into a bug in Sandstorm where it is unable to start MongoDB successfully. If
so, this is a bug in Sandstorm that probably affects many, many people, and if you report this
issue, we will be grateful; your bug report could lead to a code change that fixes many people's
Sandstorm servers. To do that, we need to hear from you.In theory, this error message can occur if your Sandstorm database (stored in
/opt/sandstorm/var/mongo) has become corrupted. So far, we have seen no instances of this in the
wild. If it does occur, you can likely recover from the situation. Even if there is a problem with
the Sandstorm MongoDB instance, note that grain data is safely stored separately, so any grain data
would not be affected.
To get further help, please open an issue on GitHub. Please include the most recent 100 lines
from the MongoDB log file, if you can.
Installing and running without root privileges
In Sandstorm v0.190 and higher, Sandstorm requires either:
The ability to launch Sandstorm as root so it can drop privileges itself, or
Unprivileged user namespaces enabled in your system's Linux kernel.
You can ask Sandstorm to do an install as non-root by passing -u to the install script. For
example:
curl https://install.sandstorm.io/ > install.sh
bash install.sh -uIf you start Sandstorm as a non-root user, Sandstorm uses unprivileged user namespaces as part of an
alternative grain isolation strategy. Some Linux kernels do not have user namespaces available, or
make them only available to root, so this article provides advice on how to enable user
namespaces. If you use the userns-based sandbox, please be sure to keep up to date with kernel
updates.
People who don't know how to change a Linux kernel. If you are a customer of a hosting
provider, please ask your hosting provider to read this page.Arch Linux users. We suggest starting Sandstorm as root instead to avoid the dependency on
user namespaces. In #36969, the Arch Linux kernel
maintainer indicated that they are not interested in supporting unprivileged user namespaces. Try
thelinux-lqxAUR package, or build your own kernel. Read the Arch Linux wiki page on
kernels for more information.Docker users. You can launch Sandstorm as root per our recommendations for
Docker in our installation guide.
Alternatively, if your system needs it, you can use the Debian-specific sysctl, but you
will need to provide--cap-add SYS_ADMIN --security-opt seccomp=unconfinedtodocker run.Debian and Ubuntu users. The Sandstorm install script can use a Debian-specific
sysctl to enable unprivileged user
namespaces. If you are unable to set it on your system, please run these commands as root and/or
upgrade your Linux kernel.
# sysctl -w kernel.unprivileged_userns_clone=1
# echo 'kernel.unprivileged_userns_clone = 1' >> /etc/sysctl.conf"RHEL and CentOS users. We suggest starting Sandstorm as root. If you must use the userns
sandbox, note that CentOS/RHEL 7.2 ships a kernel that may be able to support unprivileged
usernamespaces. In our testing, further work is needed to properly enable Sandstorm to work within
CentOS/RHEL 7.2. If you need help with this, please email
[email protected].OpenVZ users. If you use an OpenVZ-based hosting provider, please try to run Sandstorm as
root. If that does not work, please ask your hosting provider to read our installation
documentation and this document.Grsecurity kernel users. Grsecurity seems to block unprivileged user namespaces. Sandstorm
should operate properly if you start it as root. If you need use Sandstorm with user namespaces,
consider running Sandstorm without Grsecurity. You might be interested to see Sandstorm's track
record of successfully blocking exploitation of Linux kernel
vulnerabilities.Alpine Linux users. Alpine Linux enables Grsecurity by default. See the previous item and
consider using the Alpine vanilla kernel.
As an implementation detail, running install.sh with -d uses user namespaces if available, and
enables the Debian-specific sysctl on Debian/Ubuntu systems if possible.
How do I enable WebSockets proxying? or, Why do some apps seem to crash & reload?
Some Sandstorm users find that apps like Telescope and Groove Basin seem to load an initial screen
and then refresh the page, in a loop. This is typically a symptom of Sandstorm running behind a
reverse proxy that needs WebSockets proxying to be enabled.
For nginx: consult the
nginx-example.conf
that we provide. Pay special attention to:
The
map $http_upgrade $connection_upgradesection. You need to add this to the config
file for this site.The two
proxy_set_headerlines relating toUpgradeandConnection.
For apache2: consult the
apache-virtualhost.conf
that we provide. Pay special attention to the RewriteRule stanzas.
Can I use Let's Encrypt for adding HTTPS to Sandstorm?
Yes, support for Let's Encrypt was added in 0.263. To use Let's Encrypt, your Sandstorm server needs
to be able to modify your DNS records. This is made possible by the ACME.js library as long as
you use a supported DNS provider (Sandcats.io, Cloudflare, Digital Ocean, DNSimple, Duck DNS, GoDaddy,
Gandi, Namecheap, Name.com, AWS Route 53, or Vultr). You can now configure this in the admin panel.
Does Sandstorm run on ARM systems like Raspberry Pi?
Not yet, and there is currently no timeline on adding ARM support to Sandstorm.
We might revisit this in a year or two, once we're happy with the Sandstorm experience on x86-64.
You shouldn't plan on ARM support existing at any particular time. If you want Sandstorm on a small
computer, we can suggest the following, though we haven't personally tried them.
Small desktop PCs like running 64-bit Intel CPUs, such as the Asus Chromebox
M004U ($150 at time of
writing), the Dell Inspiron micro desktop
series, or any Intel NUC such as the
NUC5CPYH ($130 at time of writing). Note that for
a Chromebox, you must modify it to run Ubuntu first by following directions like
these.Jaguarboard, a 1GB RAM
single-board computer running an Intel Z3735G
64-bit CPU.
$80 at the time of writing.Intel Compute Sticks such as the CS125 running
the x5-Z8300 64-bit
CPU.
$130 at the time of writing.
We are focusing on x86-64 because we only have so much time in the day. If you're a volunteer and
interested in tackling the ARM/multi-architecture situation, then please speak up on the
related issue.
There are a few obstacles we'd need to overcome for Sandstorm to provide a good experience
on ARM.
Sandstorm app authors compile their own app packages, so we would need to either ask app
authors to cross-compile on their own systems, or we would need to set up a buildd network. If we
set up a buildd network, this would come into conflict with the Sandstorm app package signing
situation where app authors sign their binaries. They might not have a way to test the ARM
binaries that we build on the automated builders, so quality might suffer. This isn't a top
priority at the moment within Sandstorm-the-company because it would take time and attention from
other things which we think will better serve a greater number of users right now. We would welcome
help.Historically, MongoDB doesn't officially support ARM. Thankfully all new versions of MongoDB
do support ARM! Read more at this MongoDB issue.
Although some Sandstorm apps embed old versions of MongoDB, this is presumably not a big problem
anymore.
We hope to be able to provide a more satisfying answer one day. If you don't need ARM in particular,
but you want a power-efficient small computer that runs Sandstorm, see the links above.
Is Sandstorm ready for production use? Is it in beta?
Sandstorm is ready for production use, and is used by thousands of users for real work every day.
The Sandstorm team itself relies on Sandstorm extensively for our day-to-day work including project
management, collaboration, and file management, as do many other individuals and companies. As with
any software product, there are plenty of things on our roadmap that we intend to add or improve
over time, but the core functionality has been stable for a while.
Can I run Sandstorm on a totally-offline server or airgapped network?
Yes. See: Running Sandstorm offline
Why do I see strange DNS lookups in my server log?
When viewing your server's admin log, you might see DNS-related messages like this. They are
harmless and can be ignored. They are probably the result of bots scanning the Internet for security
issues that do not affect Sandstorm.
Error: Host "sandstorm-www.notyourdomain.example.com" must have exactly one TXT record.
at server/pre-meteor.js:728:16
at QueryReqWrap.asyncCallback [as callback] (dns.js:64:16)
at QueryReqWrap.onresolve [as oncomplete] (dns.js:216:10)
Error: Error looking up DNS TXT records for host "notyourdomain.example.com": queryTxt ETIMEOUT sandstorm-www.notyourdomain.example.com
at server/pre-meteor.js:728:16
at QueryReqWrap.asyncCallback [as callback] (dns.js:64:16)
at QueryReqWrap.onresolve [as oncomplete] (dns.js:216:10)The odd log messages are the result of misdirected HTTP requests (probably from bots) and the way
Sandstorm's static publishing for external domains works. There's no security issue here, nor any
action required by the server admin.
Sandstorm supports publishing static sites at domains that are not part of its "wildcard domain."
This allows you to publish a website at a domain like example.com from your Sandstorm server,
preserving the domain. To achieve this, you would make a DNS A record for example.com pointing at
your Sandstorm server. This ensures that when users navigate to example.com in their browser, the
browser sends the request to Sandstorm.
Once Sandstorm receives this request, it needs to know which grain it should dispatch this request
to. This is supported by having the user create a DNS TXT record for sandstorm-www.example.com
containing the grain's "public ID". If no such DNS record is found, Sandstorm concludes that the
domain owner has not indicated a desire to publish a particular Sandstorm grain at the domain
from the HTTP request.
What's happening in your log traces is that Sandstorm is receiving HTTP requests for those domains,
performing the DNS lookup to see what grain's static publishing folder should be used to answer
those requests, and the DNS lookup is either failing (in the case of ETIMEOUT) or returning a
response whose format surprises Sandstorm.
Sandstorm logs this event since it could indicate a configuration problem if it occurred for a
domain name that should be served from this Sandstorm server.
How do I notify the owner of a resource-hogging process?
- Identify the process via
top. cat /proc//mountinfoand find the mapping that looks like/opt/sandstorm/var/sandstorm/grains/<grain-id>/sandbox /var. This gives you the grain ID.sudo sandstorm mongoto get to the Sandstorm mongo shell.db.grains.find({_id: "<grain-id>"})to get info about the grain. In particular, theuserIdis shown.db.users.find({_id: ""})to get the user record. Look for the list ofloginCredentials, and take the first ID shown.db.users.find({_id: "<login-credential-id>"})to get info about the user identity.
This should show you the user's profile info including e-mail address, etc.
A very large grain fails to start. How can I fix this issue?
In some cases, grains with a large number of files may fail to start, and the error sandstorm/supervisor.c++:232: overloaded: inotify_add_watch: No space left on device; is logged in the grain log. This is caused by a Linux setting which limits the maximum number of inotify watches a given user account (in this case, sandstorm) may request. Due to how Sandstorm monitors storage usage, this value acts as the limit of the number of files which can exist in simultaneously open grains. Starting with the Linux kernel 5.11, the default value of this setting is dynamically adjusted based on memory, but on older kernels, it may be lower than warranted. The previous default was 8,192.
You can check the setting by executing the following command: cat /proc/sys/fs/inotify/max_user_watches
To increase this limit, add a line like fs.inotify.max_user_watches=32768 to /etc/sysctl.conf and then execute the command sysctl -p to load the configuration.
File: docs/administering/for-work.md
Sandstorm offers a variety of features intended for use by
organizations (e.g., companies) that make Sandstorm available to their members (e.g., employees).
These features used to be a part of a product called "Sandstorm for Work", but have since been
merged into the standard Sandstorm build, available to everyone.
Organizational features in depth
Defining an organization, and its impact on permissions
Many of Sandstorm's organization features depend on a server administrator specifying the group of users
that will be working together using Sandstorm. We call this organization management. You can enable
and disable organization-related features via the /admin/organization settings area.
To apply settings to all users within an organization, you must use organization management settings to
configure the boundary of your organization with regard to at least one login provider. Users within the
organization will automatically be able to log in, install apps, and create grains.
To enable this feature:
Log in to your server as an administrator.
Click your name at the top right, then Admin panel; this should take you to
/admin.Under the "Configuration" header, click "Organization settings"
Enable and configure your organization membership on a per-login-provider basis.
Login providers have different settings that are used to define your organization. A user is
considered a member of your organization if the settings for at least one login provider
declare the user to be a member. You can enable/disable this on a per-login-provider basis.
Google authentication. All users who use a particular Google Workspace domain of your choosing can
receive user status in Sandstorm. When you enable the use of Google Workspace to define the boundary
of your organization, you must specify which Google Workspace domain represents your organization.SAML authentication, including Active Directory. All users who log in via SAML can
automatically receive user status in Sandstorm. When you use SAML to define the boundary of your
organization, all users who log in via SAML are considered members of the organization. Sandstorm
supports logging in via Active Directory via support for SAML 2.0 and provides a step-by-step
tutorial.LDAP authentication. All users who log in via LDAP can automatically receive user status in
Sandstorm. When you use LDAP to define the boundary of your organization, all users who log in via
LDAP are considered members of the organization.Passwordless email login. All users who use a particular email address domain name
(e.g. @example.com) can receive user status in Sandstorm. To enable this, you must specify which
Internet domain name represents your organization.
This feature is important because, by default, when a user signs into a Sandstorm server for the
first time, Sandstorm creates a Visitor account for them. Visitors can use grains that have been
shared with them but cannot create grains of their own.
Additional organization settings
Once you have defined your organization, you can optionally configure system-wide rules based on
organization membership. This can be done from /admin/organization within your Sandstorm server.
You can disallow collaboration with users outside the organization. If you enable this option,
grains can only be seen by users logged-in as a member of your organization. This means:
Unauthenticated (aka anonymous) users cannot view grains, even if they have a sharing link.
When a user attempts to create an account or sign in, Sandstorm validates that they are part
of your organization. If not, then they may not create an account or sign in. This prevents
Visitors from using their accounts.Security note: at the moment, this setting only applies to new logins. If a user was already signed
in when you first enabled this option, the user would be able to continue to use their account even
if they're not a member of your organization.
You can make all organization users visible to each other. This setting automatically adds
users within the organization to each other's contact list so that they can share grains with each
other. The contact list is used for autocomplete when users are in the "Share access" dialog within
a grain. Disable this if you have some users whose identity should stay hidden from other users.
Authentication provider: SAML 2.0
SAML 2.0 is a passwordless single sign-on protocol. It allows a web application such as Sandstorm to
request the current user's credentials from a central service, typically administered by a
university or corporate IT team. Sandstorm's SAML support is compatible with Shibboleth, Okta,
Microsoft Active Directory, SimpleSAMLphp, and other SAML services. We have special documentation
for single sign-on with Active Directory.
To enable SAML login on your Sandstorm server, take the following steps:
Log into your Sandstorm server as an administrator.
Click Admin panel within your Sandstorm server; this should take you to
/admin.Under "Configuration", click on "Identity providers"; this should take you to
/admin/identity.In the Identity providers table, click the "Configure" button in the SAML row.
Complete the form and enabled SAML login.
Your SAML IDP should be configured to return a persistent nameID. In addition, if you are not using
Active Directory, you must configure your IDP to provide two extra attributes, email and
displayName.
The easiest way to integrate with SAML is if your SAML IDP supports reading the service provider
metadata from a URL. If it does, you can point it to your Sandstorm base URL followed by/_saml/config/default. For example: https://sandstorm.example.com/_saml/config/default
The Service URL of this server is displayed in the configuration dialog, and is always your server's
hostname plus /_saml/validate/default. For example:https://sandstorm.example.com/_saml/validate/default
Authentication provider: LDAP
LDAP is a protocol for storing information of nearly any kind; it is typically used to store data
about people who work at a company, including login credentials. Sandstorm's LDAP support allows
you to log into Sandstorm with a username and password that is checked against an LDAP store.
Sandstorm's LDAP support is compatible with Microsoft Active Directory, OpenLDAP, and many other
LDAP servers.
To enable LDAP login, take the following steps:
Log into your Sandstorm server as an administrator.
Click Admin panel within your Sandstorm server; this should take you to
/admin.Under "Configuration", click on "Identity providers"; this should take you to
/admin/identity.In the Identity providers table, click the "Configure" button in the LDAP row.
Complete the form and enabled LDAP login.
Implementation notes for LDAP that may apply to your site:
A typical LDAP configuration (e.g. Active Directory) will use an Base DN of
ou=Peoplefollowed by the LDAP version of your domain name. Forexample.com, this would beou=People,dc=example,dc=com.When logging in with LDAP, you might run hit this error:
Exception while invoking method 'login' SizeLimitExceededError. In our testing, this seems to occur with LDAP sites where multiple LDAP
objects match the username. In this case, you probably need to add a custom LDAP Search
Filter under "Additional LDAP filter criteria. Your search filter should typically take the form
of(&(something))so that it is AND'd against the default Sandstorm LDAP query used when a user
is logging in.Some LDAP servers require authentication before permitting a search. In that case, you will need
to configure an Bind user DN and Bind user password, a user and password for the search
user.In Active Directory, the
uidfield is generally not set. In a typical Active Directory setup,
set the LDAP username attribute to eithersAMAccountNamefor username-only (e.g. bob) oruserPrincipalNamefor user-at-domain (e.g. [email protected]) format login.Typically LDAP servers use the
cnfield to store the name of the person who is successfully
logging in.cnis short for common name. If your LDAP server is configured differently, please
adjust the LDAP given name attribute.
Whitelabeling
You may customize Sandstorm's appearance to make it appear more like a service of your organization.
For instance, you can:
Change the logo used when users sign in
Hide the "Troubleshooting" button on the login page
Hide the "Send feedback" link on the login page
Change the title the server shows to all its users in the top-left
To do that, visit the Admin settings area, then click Personalization and look for the
Whitelabeling options.
These features are in addition to Sandstorm's existing customization options, enabling the
admin to:
Set a server title
Set a custom splash URL on home page, as you can see on Oasis.
Change the message that users see when they receive an invitation to the server.
Set a URL for a terms of service.
Set a URL for a privacy policy.
You can read about these features in the Sandstorm administration
FAQ.
Features coming soon
We're still working on the following features:
Group management. This will allow you to share a grain with everyone in a group, such as the
marketing department, using groups from Google or LDAP. For now, you can use the
Collections app to create groups of grains
that you share with the people who need access.
Global audit logging. Monitor data across the whole organization to keep track of who has
accessed what.
File: docs/administering/guide.md
Sandstorm administrator's guide
This guide provides an overview of essential topics you'll need to know to make productive use of
your own Sandstorm self-install.
Customizing Sandstorm for your users
See these topics elsewhere in the docs:
File locations & service management
By default, Sandstorm installs within /opt/sandstorm.
- Now is a good time to
cd /opt/sandstormand uselstake a look around!
Note: If you are having trouble finding /opt/sandstorm, it could be because you need to vagrant ssh into the virtual machine that runs Sandstorm for you.
The install script creates a system
service to run Sandstorm, by default.
To start Sandstorm, run:
sudo service sandstorm startorsudo systemctl start sandstorm
(depending on your Linux distribution).To stop or restart Sandstorm, replace
startwithstoporrestartin the above command.
Within /opt/sandstorm there are a few essential files and directories.
/opt/sandstorm/sandstorm.conf- this is the Sandstorm configuration file. We sometimes refer to
this assandstorm.conffor short. Edit it by runningsudo nano /opt/sandstorm/sandstorm.conf;
after editing it, restart Sandstorm./opt/sandstorm/var/log/sandstorm.log- this is the log file for Sandstorm. If you are logged in
to a Sandstorm install as an administrator, you can view this on the web by visiting Admin
panel then clicking System log./opt/sandstorm/var/mongo- this is the data directory for MongoDB, the database engine that
stores all Sandstorm data like grain names, user names, and permissions. You can query it by
starting a Mongo shell by running:sudo sandstorm mongo./opt/sandstorm/var/sandstorm/grains- this directory contains the files and directories created
by each app instance, which we call a grain./opt/sandstorm/var/sandstorm/grains/{{grainId}}/sandbox- this directory is available within the
grain as/var, via a filesystem namespace./opt/sandstorm/var/sandcats- this directory contains configuration information for the
sandcats.io dynamic DNS service./opt/sandstorm/sandstorm-{{versionNumber}}- this directory contains Sandstorm and all its
dependencies. To install your own modified version, read our instructions on building Sandstorm
from source.
Processes and syscalls: Getting under the hood of Sandstorm
When Sandstorm is running, it launches the bundle runner, a tool that ensures other components
of Sandstorm are properly launched. The bundle runner starts by containerizing itself, using the
Linux syscalls related to namespaces, seccomp, and so forth.
The bundle runner ensures that other components of Sandstorm launch properly, including:
The auto-updater, which executes curl periodically to check for new versions of Sandstorm.
The Sandstorm shell, a nodejs process which serves HTTP(S) for visitors to your Sandstorm server.
MongoDB, the database used by Sandstorm.
The Sandstorm backend, a C++ program which itself uses namespace syscalls to launch grains.
The server monitor, which restarts the shell, MongoDB, and/or the Sandstorm backend if any of them
abruptly exit.
If a server is idle, these are the only Sandstorm-related processes on a server.
When a user navigates within the Sandstorm shell to launch a grain, a process tree is created
starting at supervisor. The per-grain supervisor containerizes and launches the processes
specified as the grain's entry point.
To manually inspect these processes, consider using strace and ps on a running Sandstorm server.
New versions and applying updates
Sandstorm itself
We release new versions of Sandstorm approximately once per week. We release them to
dl.sandstorm.io as tar.xz files. Since they contain not just
Sandstorm but all of Sandstorm's dependencies, we call them the Sandstorm bundle.
Since September 2015, we sign updates and Sandstorm verifies these
signatures.
By default, Sandstorm checks for updates every day. You can configure this behavior by editing sandstorm.conf.
This setting enables automatic updates.
UPDATE_CHANNEL=devThis setting disables it.
UPDATE_CHANNEL=noneWe intend to follow the Chrome update channels system, but for now we only have a dev channel.
We strongly recommend that you keep automatic updates enabled. This is a work in progress, but
we intend for our automatic updates to not cause any downtime.
Sandstorm apps
Sandstorm apps are distributed as SPK files. They contain contain a Linux web app and all its
dependencies, as well as metadata like the app version and author name. The SPK file format is
defined using Cap'n Proto as
package.capnp
and you can use the spk command line tool to analyze a package.
Sandstorm.io, the organization, maintains a list of packages in an app
market. The app market publishes metadata about what apps are
available, called the app index. Every day, Sandstorm downloads this file. For every app in the
app index, if a user on your Sandstorm server has an older version installed, Sandstorm creates a
notification suggesting that the user click a button to update to the latest version.
This behavior can be customized within the Admin panel under App sources. We strongly recommend
keeping this enabled. You can also point your Sandstorm install at a different app market URL and
app index URL.
Hostnames and wildcards
In sandstorm.conf, the BASE_URL specifies the URL at which your Sandstorm install assumes it is
available. For example, it might be:
BASE_URL=http://sandstorm.example.comSandstorm requires a wildcard DNS record. Each
session to each grain uses a unique, one-time-use hostname; Sandstorm uses this as part of its
security model and this requirement cannot be disabled.
Typically, people configure a wildcard record at *.sandstorm.example.com. The WILDCARD_HOST can
point at a different wildcard within the same domain name, but note that the BASE_URL andWILDCARD_HOST must be within the same domain name. Therefore, the following can work as well:
BASE_URL=http://sandstorm.example.com
WILDCARD_HOST=ss-*.example.comThis would cause Sandstorm to create hostnames of the form ss-foobar.example.com and assumes that *.example.com is set up as a wildcard record. In BIND syntax, that would be the following.
*.example.com. 3600 IN A 0.0.0.0Note that any port number that appears in BASE_URL must also appear in WILDCARD_HOST.
For SSL/HTTPS, you will also need a wildcard certificate. Read more about Sandstorm and HTTPS.
Accounts, authentication, and access control
Key concepts:
A Sandstorm grain is owned by the person who created it.
Every Sandstorm user sees only the grains they have created or the grains that have been shared with them.
Every Sandstorm user starts by seeing no apps installed, and must install apps on their own.
Sandstorm supports multiple login providers which can be enabled/disabled from the Admin panel.
There are three standard levels of users.
Visitors can use and re-share grains that have been shared with them. They cannot create grains of their own nor install apps. By default, anyone can click Sign in and become a Visitor. If you would prefer to disallow visitors entirely, you can enable the setting "Disallow collaboration with users outside the organization", found under "Organization settings" in the admin panel.
Users can install apps for their own use, create grains, and share them with others. By default, these users must be invited by an Admin.
Admins can also see the Admin panel, allowing them to invite users, modify user levels, and configure server settings like login providers and email settings.
Additionally, Sandstorm has demo accounts which are disabled by default. See the Demo mode documentation for details.
If you see a message saying your Sandstorm install has no users, read the How do I log in, if
there's a problem with logging in via the
web? frequently-asked
question.