improvement: better deploy guide

next
Timo Kösters 2021-01-01 13:47:53 +01:00
parent d7e56dbfa0
commit b4818716b8
No known key found for this signature in database
GPG Key ID: 24DA7517711A2BA4
7 changed files with 131 additions and 71 deletions

146
DEPLOY.md
View File

@ -1,53 +1,42 @@
# Deploy from source # Deploying Conduit
## Prerequisites ## Getting help
Make sure you have `libssl-dev` and `pkg-config` installed and the [rust toolchain](https://rustup.rs) is available on at least on user. If you run into any problems while setting up Conduit, write an email to `support@conduit.rs`, ask us in `#conduit:matrix.org` or [open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new).
## Installing Conduit
## Install Conduit You have to download the binary that fits your machine. Run `uname -m` to see
what you need. Now copy the right url:
You have to download the binary that fits your machine. Run `uname -m` to see what you need:
- x84_64: `https://conduit.rs/master/x86_64/conduit-bin` - x84_64: `https://conduit.rs/master/x86_64/conduit-bin`
- armv7: `https://conduit.rs/master/armv7/conduit-bin` - armv7: `https://conduit.rs/master/armv7/conduit-bin`
- armv8: `https://conduit.rs/master/armv8/conduit-bin` - armv8: `https://conduit.rs/master/armv8/conduit-bin`
- arm: `https://conduit.rs/master/arm/conduit-bin` - arm: `https://conduit.rs/master/arm/conduit-bin`
```bash ```bash
$ sudo useradd -m conduit $ sudo wget -O /usr/local/bin/conduit <url>
$ sudo -u conduit wget <url> -O /home/conduit/conduit-bin && chmod +x /home/conduit/conduit-bin $ sudo chmod +x /usr/local/bin/conduit
``` ```
## Setup systemd service ## Setting up a systemd service
In this guide, we set up a systemd service for Conduit, so it's easy to Now we'll set up a systemd service for Conduit, so it's easy to start/stop
start/stop Conduit and set it to autostart when your server reboots. Paste the Conduit and set it to autostart when your server reboots. Simply paste the
default systemd service you can find below into default systemd service you can find below into
`/etc/systemd/system/conduit.service` and configure it to fit your setup. `/etc/systemd/system/conduit.service`.
```systemd ```systemd
[Unit] [Unit]
Description=Conduit Description=Conduit Matrix Server
After=network.target After=network.target
[Service] [Service]
Environment="ROCKET_SERVER_NAME=YOURSERVERNAME.HERE" # EDIT THIS Environment="CONDUIT_CONFIG=/etc/matrix-conduit/conduit.toml"
User=root
Environment="ROCKET_PORT=14004" # Reverse proxy port Group=root
#Environment="ROCKET_MAX_REQUEST_SIZE=20000000" # in bytes
#Environment="ROCKET_REGISTRATION_DISABLED=true"
#Environment="ROCKET_ENCRYPTION_DISABLED=true"
#Environment="ROCKET_FEDERATION_ENABLED=true"
#Environment="ROCKET_LOG=normal" # Detailed logging
Environment="ROCKET_ENV=production"
User=conduit
Group=conduit
Type=simple
Restart=always Restart=always
ExecStart=/home/conduit/conduit-bin ExecStart=/usr/local/bin/matrix-conduit
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -59,43 +48,106 @@ $ sudo systemctl daemon-reload
``` ```
## Setup Reverse Proxy ## Creating the Conduit configuration file
This depends on whether you use Apache, Nginx or something else. For Apache it looks like this (in /etc/apache2/sites-enabled/050-conduit.conf): Now we need to create the Conduit's config file in `/etc/matrix-conduit/conduit.toml`. Paste this in **and take a moment to read it. You need to change at least the server name.**
```toml
[global]
# The server_name is the name of this server. It is used as a suffix for user
# and room ids. Examples: matrix.org, conduit.rs
# The Conduit server needs to be reachable at https://your.server.name/ on port
# 443 (client-server) and 8448 (federation) OR you can create /.well-known
# files to redirect requests. See
# https://matrix.org/docs/spec/client_server/latest#get-well-known-matrix-client
# and https://matrix.org/docs/spec/server_server/r0.1.4#get-well-known-matrix-server
# for more information
# YOU NEED TO EDIT THIS
#server_name = "your.server.name"
# This is the only directory where Conduit will save its data
database_path = "/var/lib/matrix-conduit/conduit_db"
# The port Conduit will be running on. You need to set up a reverse proxy in
# your web server (e.g. apache or nginx), so all requests to /_matrix on port
# 443 and 8448 will be forwarded to the Conduit instance running on this port
port = 6167
# Max size for uploads
max_request_size = 20_000_000 # in bytes
# Disabling registration means no new users will be able to register on this server
allow_registration = false
# Disable encryption, so no new encrypted rooms can be created
# Note: existing rooms will continue to work
allow_encryption = true
allow_federation = true
#cache_capacity = 1073741824 # in bytes, 1024 * 1024 * 1024
#max_concurrent_requests = 4 # How many requests Conduit sends to other servers at the same time
#workers = 4 # default: cpu core count * 2
address = "127.0.0.1" # This makes sure Conduit can only be reached using the reverse proxy
``` ```
<VirtualHost *:443>
ServerName conduit.koesters.xyz # EDIT THIS
## Setting up the Reverse Proxy
This depends on whether you use Apache, Nginx or another web server.
### Apache
Create `/etc/apache2/sites-enabled/050-conduit.conf` and copy-and-paste this:
```
Listen 8448
<VirtualHost *:443 *:8448>
ServerName your.server.name # EDIT THIS
AllowEncodedSlashes NoDecode AllowEncodedSlashes NoDecode
ProxyPass /_matrix/ http://localhost:6167/
ServerAlias conduit.koesters.xyz # EDIT THIS ProxyPassReverse /_matrix/ http://localhost:6167/
ProxyPreserveHost On
ProxyRequests off
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:14004/ nocanon
ProxyPassReverse / http://localhost:14004/ nocanon
Include /etc/letsencrypt/options-ssl-apache.conf Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/your.server.name/fullchain.pem # EDIT THIS
# EDIT THESE: SSLCertificateKeyFile /etc/letsencrypt/live/your.server.name/privkey.pem # EDIT THIS
SSLCertificateFile /etc/letsencrypt/live/conduit.koesters.xyz/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/conduit.koesters.xyz/privkey.pem
</VirtualHost> </VirtualHost>
``` ```
Then run **You need to make some edits again.** When you are done, run
```bash ```bash
$ sudo systemctl reload apache2 $ sudo systemctl reload apache2
``` ```
### Nginx
If you use Nginx and not Apache, add the following server section inside the
http section of `/etc/nginx/nginx.conf`
```
server {
listen 443;
listen 8448;
server_name your.server.name; # EDIT THIS
location /_matrix/ {
proxy_pass http://localhost:6167/_matrix/;
}
}
```
**You need to make some edits again.** When you are done, run
```bash
$ sudo systemctl reload nginx
```
## SSL Certificate ## SSL Certificate
The easiest way to get an SSL certificate for the domain is to install `certbot` and run this: The easiest way to get an SSL certificate, if you don't have one already, is to install `certbot` and run this:
```bash ```bash
$ sudo certbot -d conduit.koesters.xyz $ sudo certbot -d your.server.name
``` ```

View File

@ -86,7 +86,7 @@ pub async fn register_route(
db: State<'_, Database>, db: State<'_, Database>,
body: Ruma<register::Request<'_>>, body: Ruma<register::Request<'_>>,
) -> ConduitResult<register::Response> { ) -> ConduitResult<register::Response> {
if db.globals.registration_disabled() { if !db.globals.allow_registration() {
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::Forbidden, ErrorKind::Forbidden,
"Registration has been disabled.", "Registration has been disabled.",

View File

@ -240,7 +240,7 @@ pub async fn create_room_route(
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event."))?; .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event."))?;
// Silently skip encryption events if they are not allowed // Silently skip encryption events if they are not allowed
if pdu_builder.event_type == EventType::RoomEncryption && db.globals.encryption_disabled() { if pdu_builder.event_type == EventType::RoomEncryption && !db.globals.allow_encryption() {
continue; continue;
} }

View File

@ -33,11 +33,19 @@ pub struct Config {
#[serde(default = "default_max_concurrent_requests")] #[serde(default = "default_max_concurrent_requests")]
max_concurrent_requests: u16, max_concurrent_requests: u16,
#[serde(default)] #[serde(default)]
registration_disabled: bool, allow_registration: bool,
#[serde(default)] #[serde(default = "true_fn")]
encryption_disabled: bool, allow_encryption: bool,
#[serde(default)] #[serde(default = "false_fn")]
federation_disabled: bool, allow_federation: bool,
}
fn false_fn() -> bool {
false
}
fn true_fn() -> bool {
true
} }
fn default_cache_capacity() -> u64 { fn default_cache_capacity() -> u64 {

View File

@ -111,16 +111,16 @@ impl Globals {
self.config.max_request_size self.config.max_request_size
} }
pub fn registration_disabled(&self) -> bool { pub fn allow_registration(&self) -> bool {
self.config.registration_disabled self.config.allow_registration
} }
pub fn encryption_disabled(&self) -> bool { pub fn allow_encryption(&self) -> bool {
self.config.encryption_disabled self.config.allow_encryption
} }
pub fn federation_disabled(&self) -> bool { pub fn allow_federation(&self) -> bool {
self.config.federation_disabled self.config.allow_federation
} }
pub fn dns_resolver(&self) -> &TokioAsyncResolver { pub fn dns_resolver(&self) -> &TokioAsyncResolver {

View File

@ -786,8 +786,8 @@ impl Rooms {
#[allow(clippy::blocks_in_if_conditions)] #[allow(clippy::blocks_in_if_conditions)]
if !match event_type { if !match event_type {
EventType::RoomEncryption => { EventType::RoomEncryption => {
// Don't allow encryption events when it's disabled // Only allow encryption events if it's allowed in the config
!globals.encryption_disabled() globals.allow_encryption()
} }
EventType::RoomMember => { EventType::RoomMember => {
let prev_event = self let prev_event = self

View File

@ -36,7 +36,7 @@ pub async fn send_request<T: OutgoingRequest>(
where where
T: Debug, T: Debug,
{ {
if globals.federation_disabled() { if !globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -322,7 +322,7 @@ pub async fn request_well_known(
pub fn get_server_version_route( pub fn get_server_version_route(
db: State<'_, Database>, db: State<'_, Database>,
) -> ConduitResult<get_server_version::Response> { ) -> ConduitResult<get_server_version::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -337,7 +337,7 @@ pub fn get_server_version_route(
#[cfg_attr(feature = "conduit_bin", get("/_matrix/key/v2/server"))] #[cfg_attr(feature = "conduit_bin", get("/_matrix/key/v2/server"))]
pub fn get_server_keys_route(db: State<'_, Database>) -> Json<String> { pub fn get_server_keys_route(db: State<'_, Database>) -> Json<String> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
// TODO: Use proper types // TODO: Use proper types
return Json("Federation is disabled.".to_owned()); return Json("Federation is disabled.".to_owned());
} }
@ -390,7 +390,7 @@ pub async fn get_public_rooms_filtered_route(
db: State<'_, Database>, db: State<'_, Database>,
body: Ruma<get_public_rooms_filtered::v1::Request<'_>>, body: Ruma<get_public_rooms_filtered::v1::Request<'_>>,
) -> ConduitResult<get_public_rooms_filtered::v1::Response> { ) -> ConduitResult<get_public_rooms_filtered::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -437,7 +437,7 @@ pub async fn get_public_rooms_route(
db: State<'_, Database>, db: State<'_, Database>,
body: Ruma<get_public_rooms::v1::Request<'_>>, body: Ruma<get_public_rooms::v1::Request<'_>>,
) -> ConduitResult<get_public_rooms::v1::Response> { ) -> ConduitResult<get_public_rooms::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -484,7 +484,7 @@ pub async fn send_transaction_message_route<'a>(
db: State<'a, Database>, db: State<'a, Database>,
body: Ruma<send_transaction_message::v1::Request<'_>>, body: Ruma<send_transaction_message::v1::Request<'_>>,
) -> ConduitResult<send_transaction_message::v1::Response> { ) -> ConduitResult<send_transaction_message::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -587,7 +587,7 @@ pub fn get_missing_events_route<'a>(
db: State<'a, Database>, db: State<'a, Database>,
body: Ruma<get_missing_events::v1::Request<'_>>, body: Ruma<get_missing_events::v1::Request<'_>>,
) -> ConduitResult<get_missing_events::v1::Response> { ) -> ConduitResult<get_missing_events::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -632,7 +632,7 @@ pub fn get_profile_information_route<'a>(
db: State<'a, Database>, db: State<'a, Database>,
body: Ruma<get_profile_information::v1::Request<'_>>, body: Ruma<get_profile_information::v1::Request<'_>>,
) -> ConduitResult<get_profile_information::v1::Response> { ) -> ConduitResult<get_profile_information::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }
@ -666,7 +666,7 @@ pub fn get_user_devices_route<'a>(
db: State<'a, Database>, db: State<'a, Database>,
body: Ruma<membership::v1::Request<'_>>, body: Ruma<membership::v1::Request<'_>>,
) -> ConduitResult<get_profile_information::v1::Response> { ) -> ConduitResult<get_profile_information::v1::Response> {
if db.globals.federation_disabled() { if !db.globals.allow_federation() {
return Err(Error::bad_config("Federation is disabled.")); return Err(Error::bad_config("Federation is disabled."));
} }