Secure images for NodeBB with external camo


  • GNU/Linux

    Info:

    This tutorial is specialized for people who want to run Camo themselves. E.g. when you need clustering or have several POP's. In case you just want to use camo I recommend you visiting the original post.

    The following "variables" will be used:

    <domain>     -> your camo domain (e.g. https://camo.nodebb.org or camo.nodebb.org)
    <your.crt>   -> the path to your ssl certificate  (e.g. /home/ssl/org.nodebb.crt)
    <your.key>   -> the path to your ssl private key (e.g. /home/ssl/org.nodebb.key). This key was generated by yourself when you created your certificate sign request / .csr
    <port>       -> your camo port, either from the standalone or integrated one.
    <camo-key>   -> a secret HMAC key. You could generate this using pwgen -sB 64 
    

    Configuring NGINX for proxying camo

    Get a free SSL certificate from Let's Encrypt or StartCom, and add this new server block to your NGINX configuration:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name <domain>;
        access_log off;
        error_log /dev/null;
    
        ssl_session_cache         shared:SSL:10m;
        ssl_session_timeout       10m;
        ssl_session_tickets       off;
        ssl_prefer_server_ciphers on;
        ssl_ciphers               'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_ecdh_curve            secp384r1;
        ssl_buffer_size           1400;
        ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    
        ssl_certificate           <your.crt>;
        ssl_certificate_key       <your.key>;
    
        charset utf-8;
    
        location / {
            proxy_set_header X-Real-IP       $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host            $http_host;
            proxy_set_header X-NginX-Proxy   true;
            proxy_redirect                   off;
            proxy_http_version               1.1;
            proxy_pass                       http://localhost:<port>;
        }
    }
    

    Make sure that:

    • your ssl certificate is valid and includes your subdomain camo.domain.tld
    • you have at least 2 server blocks now in your NGINX configuration.

    Then run service nginx configtest to validate your new configuration. If it succeeds you can reload NGINX by using service nginx reload. After this you can add camo.<domain.tld> into the camo host field and reload NodeBB. Now continue with installing camo.

    Installing camo

    Camo is being configured by environment variables which is why I usually run it in docker, but here I'll provide details on how to install it directly like NodeBB. This is only useful if you want more fine grained control or clustering for sites with heavy load.

    Clone camo from GitHub by executing:

    git clone https://github.com/atmos/camo.git
    

    You can then cd into the camo folder and start it using:

    sudo PORT=<port> CAMO_KEY="<camo-key>" node server.js
    

    Other variables you could add are:

    • CAMO_HEADER_VIA: The string for Camo to include in the Via and User-Agent headers it sends in requests to origin servers. (default: Camo Asset Proxy <version>)
    • CAMO_LENGTH_LIMIT: The maximum Content-Length Camo will proxy. (default: 5242880)
    • CAMO_LOGGING_ENABLED: The logging level used for reporting debug or error information. Options are debug and disabled. (default: disabled)
    • CAMO_MAX_REDIRECTS: The maximum number of redirects Camo will follow while fetching an image. (default: 4)
    • CAMO_SOCKET_TIMEOUT: The maximum number of seconds Camo will wait before giving up on fetching an image. (default: 10)
    • CAMO_TIMING_ALLOW_ORIGIN: The string for Camo to include in the Timing-Allow-Origin header it sends in responses to clients. The header is omitted if this environment variable is not set. (default: not set)
    • CAMO_HOSTNAME: The Camo-Host header value that Camo will send. (default: unknown)
    • CAMO_KEEP_ALIVE: Whether or not to enable keep-alive session. (default: false)

    I would also recommend installing screen and forever, on Debian you would do this by executing:

    apt-get install screen && npm i -g forever
    

    and then starting your app with:

    screen -S camo sudo PORT=<port> CAMO_KEY="<camo-key>" forever server.js
    

    This runs camo in a screen you can exit by using CTRL+A+D while still letting it run in the background and preserving any error logs. forever keeps care of restarting it in case it crashes. Test if your server.js starts by manually using node though before you use them both, otherwise you'll create a process crashing and restarting really fast.


  • Community Rep

    We can probably remove the things about nodebb-plugin-camo, since this could apply to any app that wants to use Camo, yes?


  • GNU/Linux

    @yariplus true, edited accordingly.


  • Plugin & Theme Dev

    Thanks for the tutorial!



  • @lenovouser thank you for the tutorial.
    You say you used to run it in docker. If you have time, could you indicate the step?
    I start to understand docker so i think it good exercise.

    I did: git clone https://github.com/atmos/camo.git
    I get a folder camo. Then:
    cd camo
    docker build -t camo .

    but it fails on

    Step 3 : WORKDIR /app
     ---> Running in fd2fdc6ebac2
    INFO[0126] Error getting container fd2fdc6ebac25dc5eeb8b94ea2b77a3f52c8565163d38599827628b6aaoe3e45 from driver devicemapper: Error mounting '/dev/mapper/docker-8:0-149667-fd2fdc6ebac25dc5eeb8b94ea2b77a3f52c8565163d3859982762a36aa30c22a' on '/var/lib/docker/devicemapper/mnt/fd2fdc6ebac25dc5eeb8b94ea2b77a3f52c8565163d38599827628b6aa30c22a': no such file or directory 
    

    When i check the image:

    root@server01:~/docker/camo# docker ps -l
    CONTAINER ID        IMAGE                                                                     COMMAND                CREATED             STATUS              PORTS               NAMES
    fd2fdc6ebac2        6b07ff95cd74071f19d9d1d82b52ef8c166bc5779136c719eaabf4e367d60dcf:latest   "/bin/sh -c '#(nop)    16 seconds ago                                              ecstatic_elion 
    

    Thank you in advance for any help.



  • Bringing an old thread to life again, sorry!

    I'd also love some help with the instructions for running this in a Docker image. It would make life a bit easier for deploying this in DigitalOcean.


Log in to reply
 

Looks like your connection to NodeBB was lost, please wait while we try to reconnect.