UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

185 lines (179 loc) 24.7 kB
<!DOCTYPE html><html class="default" lang="en" data-base="./"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Security | Signal K</title><meta name="description" content="Documentation for Signal K"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css?cache=1767726585343"/><link rel="stylesheet" href="assets/highlight.css?cache=1767726585343"/><script defer src="assets/main.js?cache=1767726585343"></script><script async src="assets/icons.js?cache=1767726585343" id="tsd-icons-script"></script><script async src="assets/search.js?cache=1767726585343" id="tsd-search-script"></script><script async src="assets/navigation.js?cache=1767726585343" id="tsd-nav-script"></script><script async src="assets/hierarchy.js?cache=1767726585343" id="tsd-hierarchy-script"></script><link rel="stylesheet" href="assets/theme.css"/></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="index.html" class="title"><img src="assets/logo.svg" alt="Signal K"/></a><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-search"></use></svg><span class="visible@s">Search</span></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><div id="tsd-toolbar-links"><a href="https://discord.gg/uuZrwz4dCS" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"></path></svg></a><a href="https://github.com/SignalK/signalk-server" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path></svg></a><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">Security</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="security" class="tsd-anchor-link">Security<a href="#security" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>The umbrella term <em>Security</em> in Signal K server refers to the difference between running a server, that any one connected to the network can access and alter at will <strong>(unsecured)</strong> , and one with restrictions in place <strong>(secured)</strong>.</p> <p>The available security options relate to:</p> <ul> <li><strong>authentication</strong>: Users and / or connecting devices having to provide a credential to gain access to the server <em>(e.g. username &amp; password, access token, etc.)</em>.</li> <li><strong>access control</strong>: Based on the authentication, access is granted to only specific Signal K data and server configuration.</li> <li><strong>communications</strong>: Network traffic is encrypted and the identity of the server verified to protect against eavesdropping.</li> <li><strong>network services</strong>: Control which of the server's services/interfaces are configured and active <em>(e.g. does it allow unsecured read/write over the network)</em>.</li> </ul> <h2 id="enabling-security" class="tsd-anchor-link">Enabling Security<a href="#enabling-security" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>When Signal K Server does not have security enabled, the <code>Login</code> option at the top right corner of the Admin UI will not be available.</p> <p>Security can be enabled in several ways:</p> <ol> <li> <p>Using the Admin UI, select <em>Security -&gt; Users</em> and then:</p> <ul> <li>Click <strong>Add</strong></li> <li>Enter a <strong>user id</strong></li> <li>Enter a <strong>password</strong> and confirm it</li> <li>In <strong>Permissions</strong> select <strong>Admin</strong></li> <li>Click <strong>Apply</strong>.</li> <li>Restart the Signal K Server.</li> </ul> </li> <li> <p>Starting the server with the <code>--securityenabled</code> command line option</p> </li> <li> <p>Adding the following section in the settings file</p> </li> </ol> <pre><code class="JSON"><span class="hl-4">&quot;security&quot;</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;strategy&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;./tokensecurity&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> }</span> </code><button type="button">Copy</button></pre> <p>When security is enabled, the next time you access the Admin UI it will prompt you to create an administrator account.</p> <p>Security configuration is stored in file called <code>security.json</code> which will be located in the server configuration directory.</p> <h2 id="disabling-security--lost-admin-credentials" class="tsd-anchor-link">Disabling Security / Lost Admin Credentials<a href="#disabling-security--lost-admin-credentials" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>In case the administrator user credentials are lost, removing the <code>security.json</code> file and restarting the server will restore access to the Admin UI.</p> <h2 id="access-control" class="tsd-anchor-link">Access Control<a href="#access-control" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Access control lists <em>(acls)</em> allow for fine grained access to specific data in Signal K. They specify the permissions assigned to users for resources within specifc contexts and are defined within the <code>security.json</code> file.</p> <p>The following example defines acls for the self context allowing:</p> <ol> <li> <p>Anyone to read the paths <code>&quot;steering.*&quot;</code>, <code>&quot;navigation.*&quot;</code>, <code>&quot;name&quot;</code>, <code>&quot;design.aisShipType&quot;</code> and grants the admin user permission to write (update) those paths.</p> </li> <li> <p>The user <em>john</em> to read any data coming from the <code>actisense.35</code> $source.</p> </li> <li> <p>For all other paths, only the admin user to read and no one can write.</p> </li> </ol> <pre><code class="JSON"><span class="hl-0"> </span><span class="hl-4">&quot;acls&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;context&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;vessels.self&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;resources&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;paths&quot;</span><span class="hl-0">: [</span><span class="hl-4">&quot;steering.*&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;navigation.*&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;name&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;design.aisShipType&quot;</span><span class="hl-0">],</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permissions&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;subject&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;any&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permission&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;read&quot;</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;subject&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;admin&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permission&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;write&quot;</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;sources&quot;</span><span class="hl-0">: [ </span><span class="hl-4">&quot;actisense.35&quot;</span><span class="hl-0"> ],</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permissions&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;subject&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;john&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permission&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;read&quot;</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;paths&quot;</span><span class="hl-0">: [</span><span class="hl-4">&quot;*&quot;</span><span class="hl-0">],</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permissions&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;subject&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;admin&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;permission&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;read&quot;</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span> </code><button type="button">Copy</button></pre> <p><em>Note: If there is no match is found for a specific path in the acl list, then permission will be denied to that path!</em></p> <h2 id="active-network-services" class="tsd-anchor-link">Active network services<a href="#active-network-services" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Signal K Server's main network services are:</p> <ul> <li>The <em>primary Signal K http / WebSocket interface</em>, with options to use TLS encryption and authentication <em>(read/write)</em></li> <li><em>NMEA0183 data over TCP</em> on port 10110 <em>(read only)</em></li> <li><em>Signal K over TCP</em> on port 8375 <em>(read/write)</em></li> </ul> <p>In addition the user may configure any number of TCP, UDP and Websocket connections, some of which allow write access to the server.</p> <p>The security implication of these connections is that with no security options turned on <em>devices connected to the network will have both read and write access to practically all of its data and settings</em>.</p> <p>People often dismiss local network access by saying that their boat's local network is secure enough. But one very common scenario is connecting your Signal K server <em>(e.g. a Raspberry Pi)</em> to a marina wifi. Many wifi networks allow communication between all connected computers, so your Signal K server will be advertising its services over MDNS to all other connected devices.</p> <p>So in the case that your server has a manually configured connection for <em>NMEA0183 over UDP</em>, NMEA0183 data broadcast by other devices will be received and written into your SIgnal K data.</p> <p>NMEA0183 connections over TCP and UDP are inherently unsafe. There are no options for authentication and / or secure communication. In comparison Signal K over TLS and HTTP / WebSockets can provide secure, authenticated read and write access to your data.</p> <h2 id="security-headers" class="tsd-anchor-link">Security Headers<a href="#security-headers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Signal K Server uses the <code>helmet</code> middleware to set security-related HTTP headers:</p> <table> <thead> <tr> <th>Header</th> <th>Value</th> <th>Purpose</th> </tr> </thead> <tbody> <tr> <td>X-Content-Type-Options</td> <td>nosniff</td> <td>Prevents MIME type sniffing attacks</td> </tr> <tr> <td>X-Frame-Options</td> <td>SAMEORIGIN</td> <td>Prevents clickjacking (allows same-origin iframes)</td> </tr> <tr> <td>X-DNS-Prefetch-Control</td> <td>off</td> <td>Privacy protection</td> </tr> <tr> <td>X-Download-Options</td> <td>noopen</td> <td>Prevents IE from executing downloads</td> </tr> <tr> <td>X-Permitted-Cross-Domain-Policies</td> <td>none</td> <td>Blocks Flash/PDF cross-domain access</td> </tr> <tr> <td>Referrer-Policy</td> <td>no-referrer</td> <td>Privacy protection</td> </tr> <tr> <td>Strict-Transport-Security</td> <td>max-age=15552000</td> <td>Forces HTTPS (only sent on HTTPS connections)</td> </tr> </tbody> </table> <h3 id="intentionally-disabled" class="tsd-anchor-link">Intentionally Disabled<a href="#intentionally-disabled" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The following helmet features are disabled to maintain compatibility with the SignalK ecosystem:</p> <ul> <li><strong>Content-Security-Policy</strong>: Would prevent webapps (Freeboard, Instrumentpanel) from loading external resources like map tiles and CDN scripts</li> <li><strong>Cross-Origin-Embedder-Policy</strong>: Would prevent chart plotters from embedding SignalK data</li> <li><strong>Cross-Origin-Resource-Policy</strong>: Would prevent legitimate cross-origin API access from instruments and apps</li> </ul> <h2 id="reverse-proxy-configuration-trust-proxy" class="tsd-anchor-link">Reverse Proxy Configuration (Trust Proxy)<a href="#reverse-proxy-configuration-trust-proxy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>When running Signal K Server behind a reverse proxy (e.g., nginx, Apache, Traefik), the server needs to be configured to trust the <code>X-Forwarded-For</code> header to correctly identify client IP addresses.</p> <h3 id="why-enable-trust-proxy" class="tsd-anchor-link">Why Enable Trust Proxy?<a href="#why-enable-trust-proxy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Without this setting, when behind a reverse proxy:</p> <ul> <li>All requests appear to come from the proxy's IP (e.g., <code>127.0.0.1</code>)</li> <li>Rate limiting becomes ineffective (limits apply to proxy, not individual clients)</li> <li>Access logs show proxy IP instead of real client IP</li> </ul> <p>When <code>trustProxy</code> is enabled, Signal K uses the <code>X-Forwarded-For</code> header (set by your proxy) to identify the real client IP address.</p> <h3 id="configuration" class="tsd-anchor-link">Configuration<a href="#configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The <code>trustProxy</code> setting can be enabled in the Admin UI under <strong>Server Settings &gt; Options &gt; trustProxy</strong>.</p> <p>For most setups behind a local reverse proxy, simply enabling <code>trustProxy: true</code> in the Admin UI is sufficient.</p> <p>For advanced configurations (specific proxy IPs, hop counts), edit <code>settings.json</code> directly:</p> <pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;settings&quot;</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;trustProxy&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;127.0.0.1&quot;</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span> </code><button type="button">Copy</button></pre> <p>The <code>trustProxy</code> setting accepts the following values:</p> <table> <thead> <tr> <th>Value</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><code>true</code></td> <td>Trust all proxies (use with caution)</td> </tr> <tr> <td><code>false</code></td> <td>Don't trust any proxy (default)</td> </tr> <tr> <td><code>&quot;loopback&quot;</code></td> <td>Trust loopback addresses (127.0.0.1, ::1)</td> </tr> <tr> <td><code>&quot;linklocal&quot;</code></td> <td>Trust link-local addresses</td> </tr> <tr> <td><code>&quot;uniquelocal&quot;</code></td> <td>Trust unique local addresses</td> </tr> <tr> <td>Number</td> <td>Trust the first N proxies</td> </tr> <tr> <td>IP/CIDR</td> <td>Trust specific proxy addresses (e.g., <code>&quot;192.168.1.1&quot;</code> or <code>&quot;10.0.0.0/8&quot;</code>)</td> </tr> </tbody> </table> <h3 id="example-nginx-reverse-proxy" class="tsd-anchor-link">Example: nginx Reverse Proxy<a href="#example-nginx-reverse-proxy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When using nginx as a reverse proxy, configure it to pass the client IP:</p> <pre><code class="nginx"><span class="hl-1">location</span><span class="hl-0"> </span><span class="hl-5">/ </span><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-1"> proxy_pass </span><span class="hl-0">http://localhost:3000;</span><br/><span class="hl-0"> </span><span class="hl-1"> proxy_set_header </span><span class="hl-0">X-Forwarded-For $remote_addr;</span><br/><span class="hl-0"> </span><span class="hl-1"> proxy_set_header </span><span class="hl-0">X-Forwarded-Proto $scheme;</span><br/><span class="hl-0"> </span><span class="hl-1"> proxy_set_header </span><span class="hl-0">Host $host;</span><br/><span class="hl-0">}</span> </code><button type="button">Copy</button></pre> <p>And set <code>trustProxy</code> to trust only the nginx server:</p> <pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;settings&quot;</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;trustProxy&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;127.0.0.1&quot;</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span> </code><button type="button">Copy</button></pre> <h3 id="security-considerations" class="tsd-anchor-link">Security Considerations<a href="#security-considerations" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><ul> <li>Only enable <code>trustProxy</code> if you are actually running behind a reverse proxy</li> <li>Configure the value to trust only your specific proxy IP address when possible</li> <li>Using <code>trustProxy: true</code> trusts all proxies, which could allow IP spoofing if your server is directly accessible</li> </ul> </div></div><div class="col-sidebar"><div class="page-menu"><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#enabling-security"><span>Enabling <wbr/>Security</span></a><a href="#disabling-security--lost-admin-credentials"><span>Disabling <wbr/>Security / <wbr/>Lost <wbr/>Admin <wbr/>Credentials</span></a><a href="#access-control"><span>Access <wbr/>Control</span></a><a href="#active-network-services"><span>Active network services</span></a><a href="#security-headers"><span>Security <wbr/>Headers</span></a><ul><li><a href="#intentionally-disabled"><span>Intentionally <wbr/>Disabled</span></a></li></ul><a href="#reverse-proxy-configuration-trust-proxy"><span>Reverse <wbr/>Proxy <wbr/>Configuration (<wbr/>Trust <wbr/>Proxy)</span></a><ul><li><a href="#why-enable-trust-proxy"><span>Why <wbr/>Enable <wbr/>Trust <wbr/>Proxy?</span></a></li><li><a href="#configuration"><span>Configuration</span></a></li><li><a href="#example-nginx-reverse-proxy"><span>Example: nginx <wbr/>Reverse <wbr/>Proxy</span></a></li><li><a href="#security-considerations"><span>Security <wbr/>Considerations</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">Signal K</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>