{"result":{"depiction_url":null,"edges":{"references":{"objects":[{"created":"2020-05-30T05:48:16Z","object_id":{"id":1789,"is_a":["text","documentation","developerguide"],"name":"doc_developerguide_deployment_privilegedports","title":{"_type":"trans","tr":{"en":"Running on Port 80 and Port 443"}},"uri":"https:\/\/zotonic.com\/id\/1789"},"seq":1000000},{"created":"2020-05-30T05:48:16Z","object_id":{"id":1754,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_letsencrypt","title":"mod_ssl_letsencrypt","uri":"https:\/\/zotonic.com\/id\/1754"},"seq":1000000},{"created":"2020-05-30T05:48:16Z","object_id":{"id":1753,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_ca","title":"mod_ssl_ca","uri":"https:\/\/zotonic.com\/id\/1753"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"relation":{"objects":[{"created":"2020-05-30T05:48:16Z","object_id":{"id":1754,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_letsencrypt","title":"mod_ssl_letsencrypt","uri":"https:\/\/zotonic.com\/id\/1754"},"seq":1000000},{"created":"2020-05-30T05:48:16Z","object_id":{"id":1753,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_ca","title":"mod_ssl_ca","uri":"https:\/\/zotonic.com\/id\/1753"},"seq":1000000},{"created":"2020-05-30T05:48:16Z","object_id":{"id":1789,"is_a":["text","documentation","developerguide"],"name":"doc_developerguide_deployment_privilegedports","title":{"_type":"trans","tr":{"en":"Running on Port 80 and Port 443"}},"uri":"https:\/\/zotonic.com\/id\/1789"},"seq":1000000}],"predicate":{"id":303,"is_a":["meta","predicate"],"name":"relation","title":{"_type":"trans","tr":{"nl":"Relatie","en":"Relation"}},"uri":"http:\/\/purl.org\/dc\/terms\/relation"}}},"id":1482,"is_a":["text","documentation","reference"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1482"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_developerguide_configuration_port_ssl_configuration","page_url":{"en":"https:\/\/zotonic.com\/docs\/1482\/port-configurations","x-default":"https:\/\/zotonic.com\/docs\/1482\/port-configurations"},"preview_url":null,"resource":{"body":"<div>\n            \n  <aside class=\"admonition seealso\">\n<p class=\"first admonition-title\">See also<\/p>\n<p class=\"last\"><a class=\"reference internal\" href=\"\/id\/doc_module_mod_ssl_letsencrypt\"><span class=\"std std-ref\">mod_ssl_letsencrypt<\/span><\/a>, <a class=\"reference internal\" href=\"\/id\/doc_module_mod_ssl_ca\"><span class=\"std std-ref\">mod_ssl_ca<\/span><\/a>, <a class=\"reference internal\" href=\"\/id\/doc_developerguide_deployment_privilegedports#guide-deployment-privilegedports\"><span class=\"std std-ref\">Running on Port 80 and Port 443<\/span><\/a><\/p>\n<\/aside>\n<div class=\"section\">\n\n<p>Port configurations can be tricky, especially in combination with SSL.\nHere we explain all steps to come to a correctly configured installation\nwith working SSL connectivity.<\/p>\n<p>There are basically two sets of port configurations:<\/p>\n\n<p><ol class=\"arabic simple\">\n<li>The ports Zotonic <em>listens<\/em> on<\/li>\n<li>The ports an <em>outside<\/em> visitor <em>connects to<\/em><\/li>\n<\/ol>\n<\/p>\n<p>The listen ports are configured with <code class=\"docutils literal notranslate\"><span class=\"pre\">listen_port<\/span><\/code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">ssl_listen_port<\/span><\/code>.<\/p>\n<p>The outside ports are configured with <code class=\"docutils literal notranslate\"><span class=\"pre\">port<\/span><\/code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">ssl_port<\/span><\/code>. They default to\nthe <em>listen_<\/em> variations if not defined.<\/p>\n<p>Below are examples how to configure these.<\/p>\n<div class=\"section\">\n<h2>Server direct on the Internet<\/h2>\n<p>Here you can use the methods described in <a class=\"reference internal\" href=\"\/id\/doc_developerguide_deployment_privilegedports#guide-deployment-privilegedports\"><span class=\"std std-ref\">Running on Port 80 and Port 443<\/span><\/a> to get your server\non ports 80 and\/or 443.<\/p>\n<p>The port configurations would be:<\/p>\n<div class=\"table-wrapper\"><table border=\"1\" class=\"docutils\">\n\n<thead valign=\"bottom\">\n<tr><th class=\"head\">Method<\/th>\n<th class=\"head\">listen_port<\/th>\n<th class=\"head\">ssl_listen_port<\/th>\n<th class=\"head\">port<\/th>\n<th class=\"head\">ssl_port<\/th>\n<th class=\"head\">listen_ip<\/th>\n<th class=\"head\">proxy_allowlist<\/th>\n<\/tr>\n<\/thead>\n<tbody valign=\"top\">\n<tr><td>authbind<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>any<\/td>\n<td>none<\/td>\n<\/tr>\n<tr><td>setcap<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>any<\/td>\n<td>none<\/td>\n<\/tr>\n<tr><td>iptables<\/td>\n<td>8000<\/td>\n<td>8443<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>127.0.0.1<\/td>\n<td>none<\/td>\n<\/tr>\n<tr><td>http only<\/td>\n<td>8000<\/td>\n<td>none<\/td>\n<td>80<\/td>\n<td>none<\/td>\n<td>127.0.0.1<\/td>\n<td>none<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>For <em>Network Address Translation<\/em> (NAT), see the next section. The <em>proxy_allowlist<\/em> is explained\nin the section about proxies below.<\/p>\n<p>In the case of <em>iptables<\/em> we restrict Zotonic to listen on the local 127.0.0.1 address.\nThis to prevent that people can connect on port 8000 from their browsers.<\/p>\n<p>Alternatively you can run your server on the <em>outside<\/em> port 8000, though then it is impossible\nto use Let’s Encrypt certificates for SSL (as they require the server to run on the default\nhttp and https ports).<\/p>\n<\/div>\n<div class=\"section\">\n<h2>Server accessed via NAT<\/h2>\n<p>With <em>Network Address Translation<\/em> (NAT) the traffic is routed straight to the server using port\nmappings. This is typical for a situation where Zotonic runs on a local server behind a modem.<\/p>\n<div class=\"table-wrapper\"><table border=\"1\" class=\"docutils\">\n\n<thead valign=\"bottom\">\n<tr><th class=\"head\">Proxy method<\/th>\n<th class=\"head\">listen_port<\/th>\n<th class=\"head\">ssl_listen_port<\/th>\n<th class=\"head\">port<\/th>\n<th class=\"head\">ssl_port<\/th>\n<th class=\"head\">listen_ip<\/th>\n<th class=\"head\">proxy_allowlist<\/th>\n<\/tr>\n<\/thead>\n<tbody valign=\"top\">\n<tr><td>NAT (eg. modem)<\/td>\n<td>8000<\/td>\n<td>8443<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>any<\/td>\n<td>none<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>The <em>proxy_allowlist<\/em> is explained in the section about proxies below.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>Server behind a proxy like Nginx or HAProxy<\/h2>\n<p>A proxy could be <em>haproxy<\/em> or <em>nginx<\/em>. The proxy terminates the https connection and handles\nthe SSL certificates.<\/p>\n<p>Typically the proxy connects to the default ports 8000 and 8443 on the Zotonic server.\nThe proxy itself could be running on the local server or another server.<\/p>\n<div class=\"table-wrapper\"><table border=\"1\" class=\"docutils\">\n\n<thead valign=\"bottom\">\n<tr><th class=\"head\">Proxy method<\/th>\n<th class=\"head\">listen_port<\/th>\n<th class=\"head\">ssl_listen_port<\/th>\n<th class=\"head\">port<\/th>\n<th class=\"head\">ssl_port<\/th>\n<th class=\"head\">listen_ip<\/th>\n<th class=\"head\">proxy_allowlist<\/th>\n<\/tr>\n<\/thead>\n<tbody valign=\"top\">\n<tr><td>localhost proxy<\/td>\n<td>8000<\/td>\n<td>none<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>127.0.0.1<\/td>\n<td>local<\/td>\n<\/tr>\n<tr><td>proxy on LAN<\/td>\n<td>8000<\/td>\n<td>none<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>any<\/td>\n<td>local<\/td>\n<\/tr>\n<tr><td>proxy on WAN<\/td>\n<td>8000<\/td>\n<td>none<\/td>\n<td>80<\/td>\n<td>443<\/td>\n<td>any<\/td>\n<td><em>see below<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>The proxy adds the hostname, address of the visitor and protocol information (http or https) to a\nHTTP header. Zotonic reads this header to know which site to serve and if the visitor was using https\nor not.<\/p>\n<p>Everybody could add this header and then connect directly to the Zotonic server, which can then make\nwrong assumptions about the IP address of the visitor and if the visitor is on a secure connection.<\/p>\n<p>To prevent the visitor spoofing the <em>Forward<\/em> header, Zotonic will check if the <em>inside<\/em> address of the\nproxy (as seen from Zotonic, not from the visitor) is on a list of allowed proxies.<\/p>\n<p>This allowlist is specified in <code class=\"docutils literal notranslate\"><span class=\"pre\">proxy_allowlist<\/span><\/code> and can have the following values:<\/p>\n\n<p><ul class=\"simple\">\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">local<\/span><\/code> - default, only LAN addresses can connect<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">none<\/span><\/code> - no proxy exists, ignore proxy headers<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">any<\/span><\/code> - <em>insecure<\/em>, any server anywhere can be a proxy<\/li>\n<li>A tuple with a single ip address, for example: <code class=\"docutils literal notranslate\"><span class=\"pre\">{192,168,1,1}<\/span><\/code><\/li>\n<li>A string with ip addresses with optional masks, for example: <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;127.0.0.0\/8,10.0.0.0\/8,fe80::\/10&quot;<\/span><\/code><\/li>\n<\/ul>\n<\/p>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">local<\/span><\/code> check is hardcoded and very fast.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>SSL certificates<\/h2>\n<p>After the server’s listen ports are correctly configured then the SSL connection can be tested.<\/p>\n<p>Per default Zotonic will generate a self-signed certificate for all valid hostnames. Instead of these\nself-signed certificates a real certificate can be used. Check for these the modules <a class=\"reference internal\" href=\"\/id\/doc_module_mod_ssl_letsencrypt\"><span class=\"std std-ref\">mod_ssl_letsencrypt<\/span><\/a> and\n<a class=\"reference internal\" href=\"\/id\/doc_module_mod_ssl_ca\"><span class=\"std std-ref\">mod_ssl_ca<\/span><\/a><\/p>\n<p>The self-signed certificates are stored in the <code class=\"file docutils literal notranslate\"><span class=\"pre\">self-signed<\/span><\/code> subdirectory of the security directory.<\/p>\n<p>You can see the <code class=\"docutils literal notranslate\"><span class=\"pre\">security_dir<\/span><\/code> location using <code class=\"docutils literal notranslate\"><span class=\"pre\">bin\/zotonic<\/span> <span class=\"pre\">config<\/span><\/code><\/p>\n<p>Possible locations are:<\/p>\n\n<p><ul class=\"simple\">\n<li>The environment variable <code class=\"docutils literal notranslate\"><span class=\"pre\">ZOTONIC_SECURITY_DIR<\/span><\/code><\/li>\n<li>The <code class=\"file docutils literal notranslate\"><span class=\"pre\">~\/.zotonic\/security<\/span><\/code> directory<\/li>\n<li>The <code class=\"file docutils literal notranslate\"><span class=\"pre\">\/etc\/zotonic\/security<\/span><\/code> directory (only on Linux)<\/li>\n<li>The OS specific directory for application data files<\/li>\n<\/ul>\n<\/p>\n<p>The OS specific directories are:<\/p>\n\n<p><ul class=\"simple\">\n<li>On Unix: <code class=\"file docutils literal notranslate\"><span class=\"pre\">~\/.config\/zotonic\/security\/<\/span><\/code><\/li>\n<li>On macOS: <code class=\"file docutils literal notranslate\"><span class=\"pre\">~\/Library\/Application<\/span> <span class=\"pre\">Support\/zotonic\/security\/<\/span><\/code><\/li>\n<\/ul>\n<\/p>\n<p>The default is the OS specific directory.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>HTTPS and security<\/h2>\n<p>Zotonic always redirects all incoming HTTP connections to HTTPS. This can not be disabled.<\/p>\n<div class=\"section\">\n<h3>Secure cookies<\/h3>\n<p>All cookies related to authentication are set to <em>secure<\/em>. The cookie holding the authentication\ntoken has <code class=\"docutils literal notranslate\"><span class=\"pre\">SameSite<\/span><\/code> set to <code class=\"docutils literal notranslate\"><span class=\"pre\">Strict<\/span><\/code>. This can not be configured or changed.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\">\n<h2>Erlang SSL Configuration<\/h2>\n<p>The erlang ssl application is configured in the <code class=\"file docutils literal notranslate\"><span class=\"pre\">erlang.config<\/span><\/code> file. It is stored next to the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">zotonic.config<\/span><\/code> file. You can see the config files used with:<\/p>\n<div class=\"highlight-erlang notranslate\"><div class=\"highlight\"><pre><span><\/span><span class=\"n\">bin<\/span><span class=\"o\">\/<\/span><span class=\"n\">zotonic<\/span> <span class=\"n\">configfiles<\/span>\n<\/pre><\/div>\n<\/div>\n<p>If this file is missing then it can be copied from <code class=\"file docutils literal notranslate\"><span class=\"pre\">apps\/zotonic_launcher\/priv\/erlang.config.in<\/span><\/code>.\nIt contains a couple of important settings which we recommend you to change. The reason for this is that the\ndefault settings Erlang uses are unsuitable for web servers. The most important settings are listed\nbelow.<\/p>\n<dl class=\"docutils\">\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">session_lifetime<\/span><\/code><\/dt>\n<dd>Sets the maximum lifetime of session data in seconds.<\/dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">session_cache_server_max<\/span><\/code><\/dt>\n<dd>Sets the maximum number of client sessions cached by the server.<\/dd>\n<\/dl>\n<p>For more information on configuration options, please see <a class=\"reference external\" href=\"http:\/\/erlang.org\/doc\/man\/ssl_app.html\">Erlang SSL App<\/a>.<\/p>\n<\/div>\n<div class=\"section\">\n<h2>Adding your own SSL options or certificates<\/h2>\n<p>If you want to implement your own certificate handling you have to add a\nnotification observer which returns the certificates to the underlying\nHTTPS server. This can be needed if you have a site with special hostname aliases, or if\nyou want to implement automated certificate handling for a specific certificate authority.<\/p>\n<p>The notification use by the SNI (Server Name Indication) handler is:<\/p>\n<dl class=\"docutils\">\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">ssl_options{server_name=ServerName}<\/span><\/code><\/dt>\n<dd>Return the certificate, key or other ssl options. <code class=\"docutils literal notranslate\"><span class=\"pre\">ServerName<\/span><\/code> is a string (list) with the\nname of the server from the SSL handshake. You shoudl return a proplist with Erlang\n<code class=\"docutils literal notranslate\"><span class=\"pre\">ssl:ssl_option()<\/span><\/code> terms. The proplist will override the default ssl options for this\nconnection. For more information about the possible properties see <a class=\"reference external\" href=\"http:\/\/erlang.org\/doc\/man\/ssl.html\">Erlang SSL<\/a>.\nIf <code class=\"docutils literal notranslate\"><span class=\"pre\">undefined<\/span><\/code> is returned the SSL handshake will try the next SSL module. If all\nmodules return <code class=\"docutils literal notranslate\"><span class=\"pre\">undefined<\/span><\/code> then a self-signed certificate will be used.<\/dd>\n<\/dl>\n<\/div>\n<\/div>\n\n\n           <\/div>","category_id":{"id":319,"is_a":["meta","category"],"name":"reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/reference"},"content_group_id":{"id":339,"is_a":["meta","content_group"],"name":"default_content_group","title":{"_type":"trans","tr":{"en":"Default Content Group"}},"uri":"https:\/\/zotonic.com\/id\/default_content_group"},"created":"2020-05-30T05:47:23Z","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"github_url":"https:\/\/github.com\/zotonic\/zotonic\/tree\/master\/doc\/ref\/configuration\/port-ssl-configuration.rst","is_authoritative":true,"is_dependent":false,"is_featured":false,"is_protected":false,"is_published":true,"is_unfindable":false,"language":["en"],"modified":"2023-06-24T08:17:58Z","modifier_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"name":"doc_developerguide_configuration_port_ssl_configuration","pivot_geocode":null,"pivot_location_lat":null,"pivot_location_lng":null,"privacy":0,"publication_end":"9999-06-01T00:00:00Z","publication_start":"2023-06-24T08:17:58Z","slug":"port-configurations","title":"Port configurations","title_slug":"port-configurations","tz":"UTC","uri":null,"version":3937,"visible_for":0},"uri":"https:\/\/zotonic.com\/id\/1482","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1482"}},"status":"ok"}