apache-httpd.md (12258B)
1 # Apache HTTP Server 2 3 In order to use Apache as a reverse proxy for GoToSocial you'll need to have it installed on your server. If you intend for the Apache instance to also handle TLS, you'll need to [provision TLS certificates](../../advanced/certificates.md) too. 4 5 Apache is [packaged for many distributions](https://repology.org/project/apache/versions). It's very likely you can install it with your distribution's package manager. You can also run Apache using a container runtime with the [official Apache image](https://hub.docker.com/_/httpd) that's published to the Docker Hub. 6 7 In this guide we'll also show how to use certbot to provision the TLS certificates. It too is [packaged in many distributions](https://repology.org/project/certbot/versions) but many distributions tend to ship fairly old versions of certbot. If you run into trouble it may be worth considering using the [container image](https://hub.docker.com/r/certbot/certbot) instead. 8 9 ## Configure GoToSocial 10 11 We're going to have Apache handle LetsEncrypt certificates, so you need to turn off built-in LetsEncrypt support in your GoToSocial config. 12 13 First open the file in your text editor: 14 15 ```bash 16 sudoedit /gotosocial/config.yaml 17 ``` 18 19 Then set `letsencrypt-enabled: false`. 20 21 If the reverse proxy will be running on the same machine, set the `bind-address` to `"localhost"` so that the GoToSocial server is only accessible via loopback. Otherwise it may be possible to bypass your proxy by connecting to GoToSocial directly, which might be undesirable. 22 23 If GoToSocial is already running, restart it. 24 25 ```bash 26 sudo systemctl restart gotosocial.service 27 ``` 28 29 Or if you don't have a systemd service just restart it manually. 30 31 ## Set up Apache 32 33 ### Required Apache modules 34 35 You need to ensure you have a number of Apache modules installed and enabled. All these modules *should* ship with your distribution's Apache package, but they may have been split out into separate packages. 36 37 You can check which modules you have installed with `apachectl -M`. 38 39 You'll need to have the following modules loaded: 40 41 * `proxy_http` to proxy HTTP requests to GoToSocial 42 * `ssl` to handle SSL/TLS 43 * `headers` to manipulate HTTP request and response headers 44 * `rewrite` to rewrite HTTP requests 45 * `md` for Lets Encrypt, available since 2.4.30 46 47 On Debian, Ubuntu and openSUSE, you can use the [`a2enmod`](https://manpages.debian.org/bookworm/apache2/a2enmod.8.en.html) utility to load any additional modules. For the Red Hat/CentOS family of distributions, you'll need to add a [`LoadModule` directive](https://httpd.apache.org/docs/2.4/mod/mod_so.html#loadmodule) to your Apache configuration instead. 48 49 ### TLS with mod_md 50 51 !!! note 52 `mod_md` is only available since Apache 2.4.30 and still considered experimental. It works well enough in practice and is the most convenient method. 53 54 Now we'll configure Apache HTTP Server to serve GoToSocial requests. 55 56 First we'll write a configuration for Apache HTTP Server and put it in `/etc/apache2/sites-available`: 57 58 ```bash 59 sudo mkdir -p /etc/apache2/sites-available/ 60 sudoedit /etc/apache2/sites-available/example.com.conf 61 ``` 62 63 In the above `sudoedit` command, replace `example.com` with the hostname of your GoToSocial server. 64 65 The file you're about to create should look a bit like this: 66 67 ```apache 68 MDomain example.com auto 69 MDCertificateAgreement accepted 70 71 <VirtualHost *:80 > 72 ServerName example.com 73 </VirtualHost> 74 75 <VirtualHost *:443> 76 ServerName example.com 77 78 RewriteEngine On 79 RewriteCond %{HTTP:Upgrade} websocket [NC] 80 RewriteCond %{HTTP:Connection} upgrade [NC] 81 # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 82 RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L] 83 84 SSLEngine On 85 ProxyPreserveHost On 86 # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 87 ProxyPass / http://127.0.0.1:8080/ 88 ProxyPassReverse / http://127.0.0.1:8080/ 89 90 RequestHeader set "X-Forwarded-Proto" expr=https 91 </VirtualHost> 92 ``` 93 94 or, if you have [Apache httpd 2.4.47+](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#protoupgrade), you can get rid of both `mod_rewrite` and `mod_proxy_wstunnel` and simplify the whole config to: 95 96 ```apache 97 MDomain example.com auto 98 MDCertificateAgreement accepted 99 100 <VirtualHost *:80 > 101 ServerName example.com 102 </VirtualHost> 103 104 <VirtualHost *:443> 105 ServerName example.com 106 107 SSLEngine On 108 ProxyPreserveHost On 109 # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 110 ProxyPass / http://127.0.0.1:8080/ upgrade=websocket 111 ProxyPassReverse / http://127.0.0.1:8080/ 112 113 RequestHeader set "X-Forwarded-Proto" expr=https 114 </VirtualHost> 115 ``` 116 117 Again, replace occurrences of `example.com` in the above config file with the hostname of your GtS server. If your domain name is `gotosocial.example.com`, then `gotosocial.example.com` would be the correct value. 118 119 You should also change `http://127.0.0.1:8080` to the correct address and port (if it's not on `127.0.0.1:8080`) of your GtS server. For example, if you're running GoToSocial on another machine with the local ip of `192.168.178.69` and on port `8080` then `http://192.168.178.69:8080/` would be the correct value. 120 121 `Rewrite*` directives are needed to ensure that Websocket streaming connections also work. See the [websocket](./websocket.md) document for more information on this. 122 123 `ProxyPreserveHost On` is essential: It guarantees that the proxy and the GoToSocial speak of the same Server name. If not, GoToSocial will build the wrong authentication headers, and all attempts at federation will be rejected with 401 Unauthorized. 124 125 By default, apache sets `X-Forwarded-For` in forwarded requests. To make this and rate limiting work, set the `trusted-proxies` configuration variable. See the [rate limiting](../../api/ratelimiting.md) and [general configuration](../../configuration/general.md) docs 126 127 Save and close the config file. 128 129 Now we'll need to link the file we just created to the folder that Apache HTTP Server reads configurations for active sites from. 130 131 ```bash 132 sudo mkdir /etc/apache2/sites-enabled 133 sudo ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/ 134 ``` 135 136 In the above `ln` command, replace `example.com` with the hostname of your GoToSocial server. 137 138 Now check for configuration errors. 139 140 ```bash 141 sudo apachectl -t 142 ``` 143 144 If everything is fine you should get this as output: 145 146 ```text 147 Syntax OK 148 ``` 149 150 Everything working? Great! Then restart Apache HTTP Server to load your new config file. 151 152 ```bash 153 sudo systemctl restart apache2 154 ``` 155 156 Now, monitor the logs to see when the new LetsEncrypt certificate arrives (`tail -F /var/log/apache2/error.log`), and then reload Apache one last time with the above `systemctl restart` command. After that you should be good to go! 157 158 Apache HTTP Server needs to be restart (or reloaded), every time `mod_md` gets a new certificate; see the module's docs for [more information](https://github.com/icing/mod_md#how-to-manage-server-reloads). 159 160 Depending on your version of Apache HTTP Server, you may see the following error: `error (specific information not available): acme problem urn:ietf:params:acme:error:invalidEmail: Error creating new account :: contact email "webmaster@localhost" has invalid domain : Domain name needs at least one dot` 161 162 If this happens, you'll need to do one (or all) of the below: 163 164 1. Update `/etc/apache2/sites-enabled/000-default.conf` and change the `ServerAdmin` value to a valid email address (then reload Apache HTTP Server). 165 2. Add the line `MDContactEmail your.email.address@whatever.com` below the `MDomain` line in `/etc/apache2/sites-available/example.com.conf`, replacing `your.email.address@whatever.com` with a valid email address, and `example.com` with your GtS host name. 166 167 ### TLS with externally managed certificates 168 169 !!! note 170 We have additional documentation on how to [provision TLS certificates](../../advanced/certificates.md) that also provides links to additional content and tutorials for different distributions that may be good to review. 171 172 If you prefer to have a manual setup or setting SSL using a different service to manage it (Certbot, etc), then you can use a simpler setup for your Apache HTTP Server. 173 174 First we'll write a configuration for Apache HTTP Server and put it in `/etc/apache2/sites-available`: 175 176 ```bash 177 sudo mkdir -p /etc/apache2/sites-available/ 178 sudoedit /etc/apache2/sites-available/example.com.conf 179 ``` 180 181 In the above `sudoedit` command, replace `example.com` with the hostname of your GoToSocial server. 182 183 The file you're about to create should look initially for both 80 (required) and 443 ports (optional) a bit like this: 184 185 ```apache 186 <VirtualHost *:80> 187 ServerName example.com 188 189 RewriteEngine On 190 RewriteCond %{HTTP:Upgrade} websocket [NC] 191 RewriteCond %{HTTP:Connection} upgrade [NC] 192 # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 193 RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L] 194 195 ProxyPreserveHost On 196 # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758 197 ProxyPass / http://127.0.0.1:8080/ 198 ProxyPassReverse / http://127.0.0.1:8080/ 199 200 </VirtualHost> 201 ``` 202 203 Again, replace occurrences of `example.com` in the above config file with the hostname of your GtS server. If your domain name is `gotosocial.example.com`, then `gotosocial.example.com` would be the correct value. 204 205 You should also change `http://127.0.0.1:8080` to the correct address and port (if it's not on `127.0.0.1:8080`) of your GtS server. For example, if you're running GoToSocial on another machine with the local ip of `192.168.178.69` and on port `8080` then `http://192.168.178.69:8080/` would be the correct value. 206 207 `Rewrite*` directives are needed to ensure that Websocket streaming connections also work. See the [websocket](websocket.md) document for more information on this. 208 209 `ProxyPreserveHost On` is essential: It guarantees that the proxy and the GoToSocial speak of the same Server name. If not, GoToSocial will build the wrong authentication headers, and all attempts at federation will be rejected with 401 Unauthorized. 210 211 In the case of providing an initial setup for the 443 port looking for additional managing by an external tool, you could use default certificates provided by the server which you can find referenced in the `default-ssl.conf` file at `/etc/apache2/sites-available/`. 212 213 Save and close the config file. 214 215 Now we'll need to link the file we just created to the folder that Apache HTTP Server reads configurations for active sites from. 216 217 ```bash 218 sudo mkdir /etc/apache2/sites-enabled 219 sudo ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/ 220 ``` 221 222 In the above `ln` command, replace `example.com` with the hostname of your GoToSocial server. 223 224 Now check for configuration errors. 225 226 ```bash 227 sudo apachectl -t 228 ``` 229 230 If everything is fine you should get this as output: 231 232 ```text 233 Syntax OK 234 ``` 235 236 Everything working? Great! Then restart Apache HTTP Server to load your new config file. 237 238 ```bash 239 sudo systemctl restart apache2 240 ``` 241 242 ## Troubleshooting 243 244 If you cannot connect to the site in your browser, the reverse proxy setup doesn't work. Compare the Apache log file (`tail -F /var/log/apache2/access.log`) with the GoToSocial log file. Requests made must show up in both places. Double check the `ProxyPass` setting. 245 246 If you can connect but your posts don't federate and your account cannot be found from elsewhere, check your logs. Federation is broken if you see messages attempting to read your profile (something like `level=INFO … method=GET statusCode=401 path=/users/your_username msg="Unauthorized: …"`) or post to your inbox (something like `level=INFO … method=POST statusCode=404 path=/your_username/inbox msg="Not Found: …"`). Double check the `ProxyPreserveHost` setting. 247 248 If you can connect but you cannot authorize your account in a Mastodon client app, check your headers. Use `curl -I https://example.com` and look for the `Content-Security-Policy` header. If your webserver sets it, you might have to unset it. One way to do that is to use `Header unset Content-Security-Policy` in the Apache site config file (something like `example.com.conf`).