Frequently Asked Questions

The NearlyFreeSpeech.NET FAQ (*)

Programming (*)

How do I make tls-setup.sh work with my custom daemon process?

If you are using custom proxies and daemons to serve your site content, following the recommendation to use our tls-setup.sh to set up free TLS from Let's Encrypt takes an extra step.

When you request a certificate via tls-setup.sh, a temporary file is created in the /home/public/.well-known/acme-challenge directory. Let's Encrypt checks that file by requesting it from your site using the URI /.well-known/acme-challenge/. In most cases, that "just works" because Apache handles it for you. If you have a custom process handling requests for / (i.e., all requests for the site), that won't work. The request will come to your daemon instead, which will likely say "What the 🤬 is this?" and return an error, causing your TLS setup to fail.

You should do one of two things to resolve that, depending on your server type:

Once this is set up and working, leave it in place. Your certificate will need to be renewed every 60-90 days, and this is part of that process.

What is a software realm?

A site's "realm" or "software realm" refers to the combined collection of all the operating system files, programming languages, and third-party applications present in its environment. These are the tools available to your site for web applications, and for use over ssh.

Some people want the latest and greatest versions of applications, particularly programming languages, especially while they are developing a new site. Others strongly prefer things stay as stable as possible so they don't have to deal with their site breaking every time a non-backward-compatible change gets made by some application developer, especially once their site is up and working.

Likewise, security updates always run the risk of breaking things. Some people prefer to receive security updates immediately to minimize the risk of exposure. Other people prefer to defer updates to a time of their choosing, so they can deal with any problems that result, to minimize the risk of downtime.

Because all of these desires are in direct conflict, we provide multiple types of site realms. They are broadly divided into the following types:

Stable/Current
This is the default realm assigned to new sites. It receives only security updates and important (i.e. "stuff is broken") fixes. If you don't know which realm to choose, choose the Stable/Current realm.
Stable/Upcoming
This is a newer stable realm that will become the default for new sites in the future. It receives only security updates, important (i.e. "stuff is broken") fixes, and (rarely) some non-disruptive new package requests. If you want to get your stuff working in a stable environment that will receive fixes for as long as possible, choose this.
Beta
This is a realm that receives frequent updates (as often as weekly). Although it won't become stable, it serves as a blueprint for future stable realms. New packages will be installed into a beta realm first. Beta realms also receive frequent updates, including security fixes, bug fixes, and upgrades to installed packages. Programming languages and other software may receive frequent upgrades, some of which may impair backwards compatibility, without advanced notice.
Experimental
This is a realm that is not designed to become stable. It contains bleeding-edge languages or software that are grossly incompatible with other realms. Experimental realms may receive large, potentially incompatible, updates at any time. Experimental realms are not supported or recommended for any production usage.
Stable/Deprecated
This is an older stable realm that is still supported but will be obsolete soon. Once a realm becomes obsolete, any sites still using it will be automatically moved to the current Stable/Upcoming realm. Deprecated realms receive no updates.

We add new stable realms based on the then-current beta realm about every three months. These new realms are stable and reliable but remain "Upcoming" for about three months to shake out any weird defects or bugs before becoming the current stable realm. Newly-created sites will start in the current stable realm and, by default, when a new realm becomes current, sites in older realms will be automatically migrated to it.

A site's schedule for automatic realm upgrades can be adjusted via the "Realm Updates" setting in the "Config Information" box on the Site Information Panel. This gives you some control over when to upgrade. If you select the "late" update option, we recommend that you upgrade your site's realm manually about every six months to avoid falling too far behind. (The farther behind you fall, the greater the likelihood of problems when you update.) Although rare, compatibility issues are possible, so it's best to do this at a time when you are ready to deal with them.

You can also switch between available site realms, or get a list of currently-supported realms, by selecting "Edit" on the "Software Realm" line of the same box.

Caution: This is not a subtle change; if you're logged in to ssh when you change realms, it will attempt to kick you off. It is a little like rebooting. So make sure you have saved your work!

How do I set up the server to allow web applications to write files?

By default, your site is set up with secure default permissions that don't allow web applications to write files anywhere except in /tmp. You must set permissions to allow any additional locations to be written.

In order for a PHP or CGI script, or a daemon processes run as the "web" user, to write to a file, the "web" user must have write access to that file. There are two ways to accomplish this.

In order for a script or web process to create a file, it's the permissions of the directory in which the file is to be created that matter. To allow this, do either of the following:

The choice of whether to use group-write or all-write is one of personal preference. There is no meaningful difference on our system at this time. Likewise, the choice of semantic ("a+w") vs. octal (777) is one of personal preference. Just be careful not to set directories to 666 permissions, as they will not work correctly and the result can be very confusing.

If you look online, you may find advice telling you to set all directories to 777 and all files to 666. This is terrible advice. Roughly translated it means "I don't understand Unix file permissions well enough to help you, but doing this will hide the problem for now, and I'll be long gone when this terrible advice I'm giving you lets hackers completely overwrite your site."

Our system security is designed primarily to protect sites from each other; it does not (and cannot) protect sites from themselves. So while "writeable everything" may appear to work initially and it seems easy, sooner or later a flaw will be found in your site's code or in the language it's written in — especially if that language is PHP. At that point, if your site is full of writeable files and directories, hackers will make short work of it. When deciding what to make writeable, please keep in mind the old adage, "If you don't have time to do it right, when will you have time to do it over?"

We strongly discourage members from making script files and key directories (like /home/public) writeable by the web user. This setting is used by some applications to enable self-updating over the web. We discourage that practice as well; if you can update your site over the web, so can someone else, and the site may look very different when they finish with it. We recommend using out-of-band methods to update site applications. For example, we support and recommend the use of the WP-CLI command line tool to keep WordPress installations up-to-date without exposing them to massive compromise resulting from the frequent security problems WordPress is so famous for.

Therefore, the final rule of thumb for writing files is not to set anything to be writeable over the web unless you don't mind restoring it from backup after hackers get to it. We hope this encourages you to both be conservative in what you allow your application to write, and to keep good backups. 😀

How does CGI work at NearlyFreeSpeech.NET?

We support CGI scripts with a .cgi extension in any directory in any of the available CGI languages. You do not need to limit your scripts to a cgi-bin directory, but you may if you wish (they will still need a .cgi extension unless you use the SetHandler directive in your .htaccess file). If you have trouble getting your scripts to execute make sure they are uploaded with execute permissions, that the #! line is correct, and that you've used Unix-format line endings.

CGI applications may be automatically terminated if they consume excessive system resources, run for an excessively long time, or appear to operating as "daemon" style processes.

NOTE: In addition to .cgi the following "default" CGI extensions will also work: .py .pl .rb

What can I do if I want a script to run every so often on my site (like cron)?

We allow the setup of scheduled tasks that run on a regular schedule, as often as once every ten minutes. This feature is available as "Manage Scheduled Tasks" in the "Actions" box on the Site Information page.

This feature is supported for all server types including static sites and can run tasks either as the site owner or the web user.

Output from the scheduled task (stdout and stderr), if any, will be delivered by email if possible. If there is no output, no email will be sent. If your email address is bouncing or refusing messages, or if the output is extremely large, it will be diverted to a file in your site's /home/logs directory.

For tasks that need to run more frequently, you should consider a daemon process instead.

How do I customize my PHP configuration?

You can place customized PHP configuration directives in the file /home/conf/php.ini. This file does not exist by default; create it if you need it. Give the file 644 permissions, so it is readable but not writable by the webserver.

PHP will process this file after, not instead of, the system php.ini file, so you only need your site-specific changes.

This file is not parsed on every request. Changes take a few minutes of idle time to take effect. If your site is never idle, changes may never take effect. To help it along, you can run nfsn web-kick from the command line on the ssh server to force the reconfiguration. Alternatively, you can place your site in maintenance mode for a minute from the Site Information panel in our member interface.

Use the phpinfo() function to review the active config and confirm that your changes have taken effect.

Examples:

You may include any directive supported by the version of PHP you are using in this file. For more information about PHP configuration directives, see the official PHP documentation.

What is the path to the root of my site in PHP?

PHP and CGI have the same base path: /home.

To make sure you stay pointed at the right location, use the PHP-standard $_SERVER['DOCUMENT_ROOT'] value to refer to your site's public directory.

We also provide the $_SERVER['NFSN_SITE_ROOT'] variable for this purpose, in addition to DOCUMENT_ROOT. NFSN_SITE_ROOT points to your site's root directory, the parent of public and protected, making it the best choice for safely referring to the protected directory from PHP.

We strongly recommend that you use $_SERVER['DOCUMENT_ROOT'] or $_SERVER['NFSN_SITE_ROOT'] whenever possible and avoid hardcoding paths in order to avoid problems in the event of a change.

What is the best HTML editor to use with your system?

The best one is the one that works best for you. HTML editors vary widely in terms of features, methodology, and target audience. There is no way to recommend a single best tool for everyone. If the program gets the results you want and you understand how to use it, then it is right for you.

Some factors to consider in choosing a program are:

While we still use vim every day, as of 2024, our own websites are largely maintained using the JetBrains IDEs. We can enthusiastically recommend them for complex dynamic sites, and they also provide some support for editing HTML, but they have drawbacks. They aren't for site design or layout, they carry a substantial learning curve, and they're not exactly cheap. So they aren't the best choice for every situation. Visual Studio Code is free, high quality, and seems to be very popular, but also emphasizes programming over page design.

How do I alter the PHP memory limit?

PHP's default memory_limit is -1 on our system, which disables its built-in memory limit.

Although you can change this, any other value will only decrease the amount of memory available to PHP. Consequently, we recommend against setting it in almost all situations.

Regardless of this setting, system ulimits on memory allocation will continue to apply and are not user-configurable.

What references do you recommend for web technologies?

For a tutorial/HOWTO approach, we like the w3schools.com site in particular, because it gives you the ability to fiddle with their examples and see the results in real time. They have guides for HTML, CSS, JavaScript and PHP, among others.

For quick reference and looking things up, we recommend MDN, the Mozilla Developer Network. They have references for HTML, CSS, and JavaScript, among others.

The World Wide Web Consortium (W3C) defines many web standards, and they have information about HTML and CSS. The standards documents can be a bit dry, but they are the definitive final word on the subject.

Do you have register_globals enabled for PHP?

No. By default, this feature of PHP is not enabled. It is widely considered a serious security risk and we have seen a number of member sites victimized by exploits related to having register_globals enabled. We discourage its use.

However, if you understand the implications of register_globals and you are prepared to accept the increased security risks associated with its use, we have provided you with the means to enable it on a per-directory basis. Simply create an .htaccess file in your public folder containing the line:

php_flag register_globals on

You can verify that this is working by using the phpinfo() function on a PHP page. You should see register_globals set to "On" in the local context and "Off" in the global context.

If you do not need register_globals support, you do not need to take any steps to protect your site from exploits related to it.

What is the path to the root of my site for CGI scripts?

The path to the root of your site is always seen as /home by CGI scripts, by modern (5.4+) PHP, by any daemon processes you run, and by you via ssh access.

This is reflected in the NFSN_SITE_ROOT environment variable, which will always be set to /home for CGI scripts.

How do I change the version of PHP that my site uses?

To switch a site between PHP versions, follow these steps:

  1. Go to the Sites tab in our member interface.
  2. Select the name of the site you want to change in the "Short Name" column to go to the Site Information panel for that site.
  3. On the Site Information panel, select the "Edit" button on the "PHP Version" line of the "Config Information" box.
  4. On the "Site PHP Version" panel, select the version of PHP you want to use and press the "Save Changes" button.

Note: If you do not see a "PHP Version" line in your site's Config Information box, your site's selected server type may be out of date, or may not support PHP at all. To resolve this, you can change your site's server type.

How do I control what user a CGI script runs as?

By default, CGI scripts are executed as the "web" user and group, which has almost no privileges on our system. In most cases, this is the best choice, as it controls the damage that a vulnerable script can inflict. However, for some file-management and other applications, it is necessary for a script to run with the full permissions of the user that owns your files (i.e. you, a.k.a. the "me" user ID when viewed from ssh).

To this end, we allow you to set the suid and/or sgid file permission bits on CGI applications. When the suid bit is set, the web server will execute the script using the user id of the owner of the script (provided that the owner of the script is you). When the sgid bit is set, the web server will execute the script using the group id of the group that owns the script. It is safe to use the suid/sgid bits for this purpose; our system does not otherwise honor them.

Please note that there are security implications to running web scripts as your own user ID. If such a script is compromised, you will need to delete your entire site and recreate it from scratch or otherwise manually check every single file because there will be no other way to ensure that other files have not been subtly changed. For this reason, we strongly discourage the indiscriminate use of this feature as a substitute for properly setting up file permissions.

Can I compile my own CGI application on your servers?

You may be able to use our ssh environment to compile your application for our servers; we provide C & C++ compilers for this purpose. However, we only provide these tools as-is; you are completely on your own with respect to using them or getting custom CGI applications to run on our servers.

I used an absolute path in an SSI and it didn't work. What should I do?

Make sure all of your SSI (.shtml) files use relative path paths. The supported SSI for including other files or the output of CGI applications is:

<!--#include virtual="../relative/path/app.cgi" -->

The "#exec cmd" and "#include file" directives are deprecated and are not guaranteed to work at all on our system.

How do I write files from scripts run by the web server?

By default, most files and directories are not writable by the web server. This is an important security precaution, as this prevents minor (and, sadly, common) security flaws in tools like PHP from turning into catastrophic site-wide destruction.

Consequently, the first step is to determine whether you should make a given file or directory writeable by the web server (e.g. from PHP or a CGI script). Here is our official recommendation on that subject:

No file should ever be both modifiable over the web and executable over the web.

For example, no PHP file or CGI script should ever be web-writeable. Writeable content should be minimized and limited to static items like graphics.

Once you have determined that it's appropriate to make something writeable, the specific requirements differ depending on whether you are modifying an existing file or creating a new one:

(Files created by the web server will generally be writeable by the web server by default.)

The web server runs as the "web" user and is in (only) the "web" group. Each site also has its own private user and group unique to that site. When you create a file, it will go into the site's private user and group. As a result, there are three ways to mark a file or directory as writeable by the web server.

So, setting files or directories to be writable by the web server is a two step process:

  1. Check the user and group ownership of the file and/or parent directory (usually shown by SFTP/FTP clients or the ls -l shell command) to determine whether the web server will be treated as user, group, or other when accessing it.
  2. Make sure that the appropriate user, group, or other write permission is set via chmod on the command line or the equivalent function in your SFTP/FTP tool.

Usually people have trouble getting the web server to write files, but the reverse problem is also possible: when the web server creates files, it is possible for it to set them such that you can't access (or delete) them. If this happens, you can repossess the offending files. To prevent it from happening in the first place, make sure your scripts use an appropriate umask, such as 002. This will cause files and directories to be created with read and write permissions for the web group, which you are in, so you will retain access to them.

How do I protect an upload directory from being exploited?

Many types of sites have a directory for user-uploaded content. Graphics related to posted articles, or avatar images for users, etc. Securing these can be very tricky. We recommend dividing this process into two steps.

First step: Your code should limit what types of files to upload. For example, if you are uploading forum avatars, it might be appropriate to allow jpg, png, and gif files. If you are working on a project team website for school, you might be uploading a lot of .pptx or .pdf files.

Watch out for multiple file extensions! It's not enough to just check if the file has ".jpg" in it, because it might be named "exploit.jpg.php" or "exploit.php.jpg." Apache parses file extensions individually, so both of those examples will be executed as PHP. (Although exploit files are only rarely so helpful as to have "exploit" in the name!)

If you're using application software, like WordPress, it may take care of this first step for you. If not, you'll have to code it yourself. Here is a PHP starting point. (And here is the unit test for that starting point.)

Second step: You should place an .htaccess file in any web-writeable directory that will prevent execution of files that slip past or that get onto the site through some other vulnerability. Create or add to that directory's .htaccess file with something like this:

<FilesMatch "\.(cgi|php|pl|py|rb)">
Require all denied
</FilesMatch>

This is hardly infallible, but will foil many hacking attempts, and should be included in any directory that contains uploaded or cached content. Depending on your site, you may want to add html, js, and css to the list of prohibited extensions.

To reverse this restriction for a subdirectory (rarely needed and even more rarely a good idea), create or add to that subdirectory's .htaccess file with content like:

<FilesMatch "\.php">
Require all granted
</FilesMatch>

In the case of adding blocking execution in a directory, always block everything. In the case of re-allowing execution in a subdirectory, allow only the specific type of execution you need. The above example re-allows PHP.

These steps cannot guarantee that your site's upload directory can't be exploited, but they will protect it from most of the generic bulk attacks that are designed to exploit known vulnerabilities on sites with a default configuration.