Logo

Proxy Server - Version 1.2.0


Introduction


This documentation will show you all of Acacia's features. Please go through the documentation carefully to understand how to configure your Acacia proxy server properly. No coding experience is required. In fact, you won't have to code at all! You will just have to edit a couple of configuration files.

Requirements #back to top

You will need a proper Node.js environment to use this proxy server. Acacia works best with the latest Node.js version, which is v12.6.0 at the time of writing. Any higher version should be ok. If you don't have a Node.js environment yet, here is a little tutorial on how to set it up.

  1. You can install Node.js on your local computer. However, you'll probably want to use it on a public server. My recommendation is a CentOS 7 VPS on OVH (this is not an affiliation link and I don't get money from them, it's just what I like).
  2. Open a terminal (Linux / Mac) or command line (Windows)
  3. [Linux / Mac] Install nvm (Node.js Version Manager) by wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash and run export NVM_DIR="${XDG_CONFIG_HOME/:-$HOME/.}nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" to load it immediately. If you have trouble installing or you want the latest version, please follow the nvm official documentation here.
  4. [Windows] You can download the latest nvm (Node.js Version Manager) installer from here. Choose nvm-setup.zip. You will find the full documentation here.
  5. Run nvm install 12.6.0 in your terminal or command line.
  6. Run node -v to check that Node.js is installed and that the version is 12.6.0.
  7. Run npm -v to check that npm is also there.
  8. You're all set!

nvm will let you install multiple Node.js versions on the same machine. You can switch between installed versions by nvm use [VERSION_NUMBER]. You will have to install global npm packages again for each version. On a Linux / Mac, you will need to run nvm alias default [VERSION_NUMBER] to set a default Node.js version. The default version will be loaded each time you open a new terminal.

Installation #back to top

Welcome to the Acacia proxy server! In this section we will assume that you have a proper Node.js environment installed (see the Requirements section above if you haven't), we will install the dependencies and run your proxy for the first time.

Installation

Extract the acacia folder to a location of your choice. On a terminal / command line, cd into this folder. For example, if your location is /root/acacia, run cd /root/acacia.

Now run npm install to install the Node.js dependencies from npm (Node.js Package Manager).

Running

Run node index or node index.js in your terminal / command line.

If you want your proxy to be publicly available, you must open the exposed ports in your firewall. Acacia's default ports are 80 (HTTP) and 443 (HTTPS).

Keep running

In order to keep a Node.js process running, the best choice is pm2. Install pm2 globally by running npm install -g pm2.

Stop Acacia if it is still running. Now run pm2 start index.js --name Acacia to start your Acacia process through pm2. pm2 will now manage your process.

You can still restart Acacia by using pm2 restart Acacia or read the console logs by using pm2 monit.

PHP Support

PHP is supported through PHP-FPM (FastCGI). You will need to install PHP-FPM and have it running in order to parse PHP requests. Here are some links on how to install PHP-FPM with PHP 7.3: Windows, CentOS 7.

More accurate tutorials will be published soon on the Honeyside Forum. In the meanwhile, if you need help with a specific platform, feel free to ask!

Once PHP-FPM is installed, enable PHP support in Acacia.

From now on, we will assume pm2 usage for process management. However. you are free to use any other tool to run and restart your process.

Overview #back to top

Acacia is a proxy server with reverse proxy, load balancing and static file serving capabilities.


File Structure - #back to top

All of the JS source is kept in a single file for convenience and performance: the index.js file. In future releases, we may consider to split it into multiple files. You will almost certainly never need to edit this file directly. Even if you find a bug, it's best to contact the Honeyside support than to edit the file yourself.

There are two configuration files: options.js and the config file.

options.js is the environment configuration file. Here you can enable or disable logging to console or to file. You can edit the number of workers (or sub-processes) in the cluster. In future releases, this file will hold the web control panel administrative credentials, too.

The config file is the main configuration file. The config file can be either in JS format, either in JSON format. You can choose between providing a config.js or a config.json file. If there is both a JS and a JSON config file, the JS file will be used.

Features - #back to top

Acacia offers the following features:

  • 1. Listens on any port of choice, either with or without SSL. By default, 80 and 443.
  • 2. Hostname / IP matching & default hostname.
  • 3. Hostname / IP aliasing (serve same content as another configured hostname, without redirecting).
  • 4. Path regex matching.
  • 5. SSL certificates, manual or provided by Let's Encrypt. Let's Encrypt certificates require port 80 to be publicly exposed.
  • 6. Hostname redirects with matching port and protocol.
  • 7. Redirects, both temporary and permanent.
  • 8. Reverse proxy.
  • 9. Static file serving from a specified location.
  • 10. SSL redirect to 443.
  • 11. Path rewrite when proxying requests.
  • 12. Change origin feature to forward or not forward the hostname to the target.
  • 13. WebSocket reverse proxying.
  • 14. Mount static directories on a specific path.
  • 15. Balance load by sequentially proxying to different targets.
  • 16. Log everything to file.
  • 17. DNS Proxy.
  • 18. PHP Support through PHP-FPM (FastCGI).
  • 19. WordPress support.
  • 20. WordPress permalinks setting.

Options #back to top

Power Options

                            {
                                powerOptions: {
                                    appName: 'Acacia Proxy Server',
                                    appNameColor: 'blue',
                                    numWorkers: 1,
                                    enableLog: true,
                                    enableConsole: false
                                }
                            }
                        

Acacia uses koa-power underneath.

appName is the string that will be displayed in the logs when you start Acacia.

appNameColor is the color of the string. Supported values are black, red, green, yellow, blue, magenta, cyan, white, gray, grey, rainbow, zebra, america, trap, italy, random. Color will appear in the console but not in the file log.

numWorkers is the number of sub-processes of the cluster. It's best if the number of workers matches the number cores of your machine. When a process is busy with a client, a second process listens for requests and so on. When all workers are busy, requests are queued and wait for a worker to be available.

enableLog enables logging to file. The default file is power.log.

logFileName changes the log file name. You must provide a full path.

enableConsole enables logging to console.

PHP Support

                            {
                                phpSupport: false,
                                phpOptions: {
                                    fpmPort: 9000,
                                    serverPort: 8080
                                }
                            }
                        

In order to enable PHP support, set phpSupport to true.

If set to false, servers with proper PHP settings will be treated as static files servers, instead of PHP parsers.

fpmPort is the port at which PHP-FPM (FastCGI) is running. Default value is 9000.

serverPort is the port at which the PHP parser will be running. This port shouldn't be exposed publicly and will only be used internally by Acacia. Default value is 8080.

Usage #back to top

Example - #back to top

module.exports = {
    aliases: {
        "localhost": "127.0.0.1",
        "www.example.com": "example.com"
    },
    redirects: {
        "example.com": "www.example.com"
    },
    certs: {
        default: {
            type: "path",
            cert: "certs/127.0.0.1.cert",
            key: "certs/127.0.0.1.key"
        },
        "127.0.0.1": {
            "type": "path",
                "cert": "certs/127.0.0.1.cert",
                "key": "certs/127.0.0.1.key"
        },
    },
    standard: [80],
    ssl: [443],
    dns: ['8.8.8.8', '4.4.4.4'],
    servers: {
        "80": {
            "127.0.0.1": [
                {
                    forceSSL: true
                }
            ],
            "example.com": [
                {
                    location: "/root/example.com"
                }
            ]
        },
        "443": {
            "127.0.0.1": [
                {
                    location: "/root/static",
                    regex: "^\/static.*"
                },
                {
                    mount: "/admin",
                    location: "web/admin",
                    regex: "^\/admin.*"
                },
                {
                    location: "/root/public/sad.group",
                    proxy: "https://jsonplaceholder.typicode.com/todos/1",
                    regex: "^\/todos.*",
                    rewrite: {
                        regex: "/[0-8]*$",
                        output: ""
                    },
                    changeOrigin: true,
                    secure: false,
                    ws: true
                },
                {
                    balance: ["http://s1.example.com", "http://s2.example.com"],
                    secure: false,
                    regex: "^\/balance.*"
                },
                {
                    proxy: "http://localhost:3000"
                }
            ]
        }
    }
};
                                

Structure - #back to top

In this section we will analyze the structure of the config.js / config.json file. The config file is the single source of truth for your Acacia proxy server. Of course, if you think that your JS file is getting too big, you can always split it into multiple modules by using Node.js require() and module.exports. The JSON format is advised for managing Acacia programmatically (alias, for when you want another software to mess with Acacia, instead of typing the configuration manually).

Remember! Every time you change the config file, you have to restart Acacia. If you are using pm2, you can pm2 restart Acacia to reload config.

The config object has the following properties:

  • 1. aliases (object)
  • 2. certs (object)
  • 3. redirects (object)
  • 4. standard (array)
  • 5. ssl (array)
  • 6. dns (array or object)
  • 7. servers (object)

An alias is a domain name or IP that will produce the same result of its value. For example, if the value of the localhost alias is 127.0.0.1, every localhost request will receive the same response as in a 127.0.0.1 request.

A cert is an object describing how a specific domain will be handling SSL.

A redirect is a 301 Moved Permanently that will redirect the whole domain / IP to another domain / IP (not URL!). If you are looking for more refined redirects, have a look at the servers redirect configuration below.

standards is an array of HTTP ports. Acacia will be listening on these ports. Make sure that they are available and not in use by other applications!

ssl is an array of HTTPS ports. Acacia will be listening on these ports.

dns is an array of DNS proxy targets or an object of DNS server / proxy configuration options.

servers is the proxy behavior, split by port, domain / IP and path regex. Each server can have the following properties: regex, forceSSL, location, proxy, mount, balance, redirect, rewrite, changeOrigin, ws, secure, options. We'll see these in detail in a moment.

Priority - #back to top

Here are some basic priority rules:

  • 1. aliases are applied before redirects.
  • 2. redirects are applied before servers.

Within a server configuration, the following rules apply:

  • 1. regex is evaluated first.
  • 2. If regex is undefined, the default regex ".*" will match any path.
  • 3. forceSSL will redirect to port 443, same hostname and same path.
  • 4. redirect will apply.
  • 5. location will be used to serve static files.
  • 6. If a mount path is specified, it will apply to the location above.
  • 7. balance will proxy requests, distributing load among the specified targets.
  • 8. proxy will proxy requests to the specified target.
  • 9. All other rules will apply to the proxy requests. ws, changeOrigin, secure and options will change the proxy behaviour.
  • 10. rewrite will change your path to a new path, when proxying your request. The rewrite target will be invisible to Acacia clients.

Ports - #back to top

standard: [80],
ssl: [443]
                                

standards is an array of HTTP ports. Acacia will be listening on these ports. Make sure that they are available and not in use by other applications!

ssl is an array of HTTPS ports. Acacia will be listening on these ports and it will apply the available SSL certificates.

If you need Acacia to be publicly exposed (you almost certainly will), remember to open these ports in your firewall!

DNS - #back to top

dns: [
    '8.8.8.8', '4.4.4.4'
}
                                

Acacia's DNS Proxy configuration can take an array of balanced targets. A default DNS proxy server will start on port 53.

{
    port: 53,
    host: '127.0.0.1',
    nameservers: [
        '8.8.8.8',
        '8.8.4.4'
    ],
    servers: {
        'google.com': '8.8.8.8',
        'cc': '8.8.4.4'
    },
    domains: {
        'dev': '127.0.0.1'
    }
}
                                

Acacia's DNS Proxy configuration can also take an object descriptor, like above.

port is the port of your DNS Proxy (default 53).

host is the host of your DNS Proxy (default 127.0.0.1).

nameservers is the array of targets of your DNS Proxy.

servers is an object of domain-specific or tld-specific nameservers. For example you can reroute all DNS queries for "google.com" to 8.8.8.8.

domains is an object of domain-hardcoded answers. If you specify a domain, Acacia will act as a DNS server, instead of a DNS proxy.

Servers - #back to top

servers: {
    "80": {
        "127.0.0.1": [
            {
                forceSSL: true
            }
        ],
        "example.com": [
            {
                location: "/root/example.com"
            }
        ]
    },
    "443": {
        "127.0.0.1": [
            {
                location: "/root/static",
                regex: "^\/static.*"
            },
            {
                mount: "/admin",
                location: "web/admin",
                regex: "^\/admin.*"
            },
            {
                location: "/root/public/sad.group",
                proxy: "https://jsonplaceholder.typicode.com/todos/1",
                regex: "^\/todos.*",
                rewrite: {
                    regex: "/[0-8]*$",
                    output: ""
                },
                changeOrigin: true,
                secure: false,
                ws: true
            },
            {
                balance: ["http://s1.example.com", "http://s2.example.com"],
                secure: false,
                regex: "^\/balance.*"
            },
            {
                proxy: "http://localhost:3000"
            }
        ]
    }
}
                                

Servers are the fundamental unit of the Acacia proxy. The servers object has port properties. For each port object, there are domain properties. For each domain, there's an array of servers. Each server can have the following properties: regex, forceSSL, location, proxy, mount, balance, redirect, rewrite, changeOrigin, ws, secure, options. Let's see them in detail.

A regex is a Regular Expression used to match request paths. Must be a string. For example, "word$" will match any path that ends with "word".

forceSSL will redirect to port 443, same hostname and same path. Must be a boolean.

location will serve static files from a file system location. Location must be a string. If location starts with "/" it will be considered absolute, otherwise relative. You can use "/" slashes on Windows, too.

php can be true or false. If set to true, Acacia will parse PHP files in the specified location using PHP-FPM. PHP Support must be enabled.

wordpress can be true or false. If set to true, Acacia will support WordPress permalinks. If set to false, it will return 404 not found instead.

rewriteToIndex is the same as wordpress, for now (will only work with PHP files). In future versions, it will rewrite to index.html, when PHP is disabled.

proxy will proxy your request to a target. Target must be a string.

mount will mount a location on a specific path. Must be a string. It will only work with static files.

balance will proxy your requests, distributing your load across multiple targets. Must be an array of strings.

redirect will redirect your requests. Can be either a string (301 by default) or an object specifying a status and a location. Status must be a number (HTTP status) and location must be a target URL.

rewrite will change (or rewrite) the proxied path. Applies only to proxied requests and not to static files. Must be an object. This object can have regex and output properties. Regex will match a string in the path, output will replace this string.

changeOrigin will send the request's hostname along with the proxy request. Must be a boolean. If set to true your target server won't notice being behind a proxy.

ws must be a boolean. It will enable WebSocket proxy to the target(s).

secure will verify SSL certificates, for secure proxy targets.

options is an object that can contain all of the other options from node-http-proxy

Aliases - #back to top

aliases: {
    "localhost": "127.0.0.1",
    "www.example.com": "example.com"
}
                                

aliases is an object. Each property is an alias.

An alias is a domain name or IP that will produce the same result of its value. For example, if the value of the localhost alias is 127.0.0.1, every localhost request will receive the same response as in a 127.0.0.1 request.

Redirects - #back to top

redirects: {
    "example.com": "www.example.com"
}
                                

redirects is an object. Each property is an hostname and each value is its target hostname. Target must be an URL.

Certificates - #back to top

certs: {
    default: {
        type: "path",
        cert: "certs/127.0.0.1.cert",
        key: "certs/127.0.0.1.key"
    },
        "127.0.0.1": {
            type: "path",
            cert: "certs/127.0.0.1.cert",
            key: "certs/127.0.0.1.key"
    },
    "example.com": {
        type: "letsencrypt",
        email: "admin@example.com"
    }
}
                                

certs is an object. Each property is an hostname. You can set a certificate for each hostname here or you can serve a "default" certificate. The default certificate is required.

There are two kind of certificates: "path" and "letsencrypt".

Path certificates are local files. For each certificate you must provide a cert and a key. You can also provide a ca.

Let's Encrypt will try to generate free SSL certificates on Acacia restart. You must provide an email. Remember to open and expose publicly port 80, otherwise Let's Encrypt will fail. Too many production failures may result in a temporary ban. By using Let's Encrypt, you agree automatically to their Terms of Service.

Support #back to top

Please remember you are using an open source piece of software and you have not paid for a full-time software development agency. Occasionally we will help with small tweaks, but these requests will be put on a lower priority due to their nature. Support is also 100% optional and we provide it for your connivence, so please be patient, polite and respectful.

Please use the Honeyside Forum for support requests. This way, your questions will be available for all Honeyside users to be read and answered. We do not offer email support for open source software. Do not email us directly unless you want to pay for premium support. Use the support forum instead.

Support for our items includes:
  • * Responding to questions or problems regarding the item and its features
  • * Fixing bugs and reported issues
  • * Providing updates to ensure compatibility with new software versions
Item support does not include:
  • * Customization and installation services
  • * Support for third party software and plug-ins
Before seeking support, please...
  • * Make sure you have read through the documentation and any related video guides before asking support on how to accomplish a task.
  • * Make sure to take a look at the Honeyside Forum first.
  • * Make sure you are running Acacia in a proper Node.js environment. See the Requirements section above for more.
  • * If you have customized your Acacia installation and now have an issue, back-track to make sure you didn't make a mistake. If you have made changes and can't find the issue, please provide us with your changelog.
  • * Almost 80% of the time we find that the solution to people's issues can be solved with a simple "Google Search". You might want to try that before seeking support. You might be able to fix the issue yourself much quicker than we can respond to your request.

Version History (Changelog) #back to top

Thank you for using Acacia and welcome to Honeyside!


Changelog


                                        -----------------------------------------------------------------------------------------
                                        Version 1.2.0 - February 11, 2020
                                        -----------------------------------------------------------------------------------------
                                        - Acacia becomes open source
                                        -----------------------------------------------------------------------------------------

                                        -----------------------------------------------------------------------------------------
                                        Version 1.2.0 - July 31st, 2019
                                        -----------------------------------------------------------------------------------------
                                        - added PHP support through PHP-FPM
                                        - added WordPress support
                                        - added support for WordPress permalinks
                                        -----------------------------------------------------------------------------------------

                                        -----------------------------------------------------------------------------------------
                                        Version 1.1.0 - July 29th, 2019
                                        -----------------------------------------------------------------------------------------
                                        - added DNS proxy support
                                        -----------------------------------------------------------------------------------------

                                        -----------------------------------------------------------------------------------------
                                        Version 1.0.0 - July 20th, 2019
                                        -----------------------------------------------------------------------------------------
                                        - first version of the Acacia proxy server
                                        -----------------------------------------------------------------------------------------

                                      

Copyright and license #back to top

Copyright © Honeyside - Released under MIT license