<style>
.reveal code, .reveal .code {
background-color: #2d2d2d;
}
</style>
<!-- .slide: data-epfl-logo="on" -->

<div>
<div style="text-align:right">
<img src="https://epfl-si.github.io/elements/svg/epfl-logo.svg" style="border: 8px solid #353535; width:100px" />
<br>
<small>Nicolas Borboën <nicolas.borboen@epfl.ch></small>
</div>
</div>
---
<!-- .slide: data-background="https://i.imgur.com/HEjRBtY.jpg"-->
## About
This is a quick recap about some SSH tips & tricks that every one should know about.
---
## Agenda
* History
* SSH Basics
* Config file
* Authorized keys
* Type of keys
* Managing key
* Exercices
* Bonus
---
## Key points
* [How to generate a **Ed25519** key](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Generating-Ed25519-Key)
* [Managing multiple ssh keys](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Managing-multiple-ssh-keys)
* [Manage 2 identities with Git](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Manage-2-identities-with-Git)
* [How to get your GIT config on the remote server](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Example-SendEnv-sshconfig)
* [X11 Forwarding](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Forward-X11)
* [How to use DynamicForward / **SOCKS5**](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#Dynamic-port-forwarding)
* [SSHFS](https://hackmd.io/3u3tkF2QS4eOEmaNxoC3WQ?view#SSHFS)
* Tunnel
---
<!-- .slide: data-background="https://i.imgur.com/zQGkI70.jpg"-->
# History
The **goal of SSH** was to **replace** the earlier rlogin, TELNET, FTP and rsh protocols, which did not provide strong authentication nor guarantee confidentiality.
<small>https://en.wikipedia.org/wiki/Secure_Shell</small>
----
## Tatu Ylonen
* SSH-1: 1995 (Tatu Ylonen - https://ylonen.org/)
* SSH-2: 2006 (https://www.vandyke.com/technology/drafts.html)
----
## Closed source
> Rapidly after Tatu's 1.2.12 release (ed 1999), newer versions bore successively more restrictive licenses, even though libgmp was still included and necessary for using the software. That effectively made SSH a GPL violation.
<small>https://www.openssh.com/history.html</small>
----
<!-- .slide: data-background="https://i.imgur.com/RqJtZfq.jpg"-->
## OpenSSH

----
## OpenSSH
> <small>OpenSSH (also known as OpenBSD Secure Shell) is a suite of secure networking utilities based on the Secure Shell (SSH) protocol, which provides a secure channel over an unsecured network in a client–server architecture.
</small>
<small>https://en.wikipedia.org/wiki/OpenSSH</small>
----
## OpenSSH
<small>The OpenSSH suite includes the following command-line utilities and daemons: **scp** (a replacement for rcp), **sftp** (a replacement for ftp to copy files between computers), **ssh** (a replacement for rlogin, rsh and telnet to allow shell access to a remote machine), **ssh-add** and **ssh-agent** (utilities to ease authentication by holding keys ready and avoid the need to enter passphrases every time they are used), **ssh-keygen** (a tool to inspect and generate the RSA, DSA and Elliptic Curve keys that are used for user and host authentication ), **ssh-keyscan** (which scans a list of hosts and collects their public keys ), **sshd** (the SSH server daemon).</small>
---
<!-- .slide: data-background="https://i.imgur.com/wSml9xB.jpg"-->
# Basics
----
## b.a.-ba 1
`ssh [...options...] [-p port] [user@]hostname [command]`
----
## b.a.-ba 2
**From**
`ssh [...options....] [-p port] [user@]hostname [command]`
**to**
`ssh mnemonic/alias`
---
<!-- .slide: data-background="https://i.imgur.com/3LVHR8d.png"-->
# Config
<br>
<br>
<br>
<br>
https://linuxize.com/post/using-the-ssh-config-file/
----
## man ssh_config
```shell=
ssh(1) obtains configuration data from the following
sources in the following order:
1. command-line options
2. user's configuration file (~/.ssh/config)
3. system-wide configuration file (/etc/ssh/ssh_config)
```
----
## ~/.ssh/config
```sh=
Host hostname1 mnemonic
SSH_OPTION value
SSH_OPTION value
Host hostname2
SSH_OPTION value
Host *
SSH_OPTION value
```
----
## .ssh/config (Example 1)
```sh=
Host gitlab
HostName gitlab.epfl.ch
User root
Port 2202
ForwardAgent yes
DynamicForward 3333
SendEnv GIT_*
```
----
## .ssh/config (Example 2)
```sh=
Host darsrv6
User nborboen
ForwardAgent yes
ForwardX11 no
DynamicForward 3333
Host darsrv1 grantsprod darsrv2 grantsbkp darsrv3 grantsdev
User nborboen
ForwardAgent yes
ForwardX11 no
ServerAliveInterval 60
TCPKeepAlive yes
ProxyJump darsrv6
```
----
## Notes for MacOS users
If you’re using macOS Sierra 10.12.2 or later, to load the keys automatically and store the passphrases in the Keychain, you need to configure your `~/.ssh/config` file:
```sh=
UseKeychain yes
```
----
## Recap
* Host
* Aliases
* User
* Port
* IdentityFile
* ForwardAgent
* ForwardX11
* DynamicForward
* ProxyJump
* SendEnv
* ...
---
# Authorized keys
<!-- .slide: data-background="https://i.imgur.com/qgBSOUO.jpg"-->
----
## Info
> <small>The **authorized_keys** file in SSH specifies the SSH keys that can be used for logging into the user account for which the file is configured. It is a highly important configuration file, as it configures permanent access using SSH keys and needs proper management.</small>
<small>https://www.ssh.com/ssh/authorized_keys</small>
----
## Authorized keys IRL
[](https://i.imgur.com/gb1dYVN.jpg)
<small>https://twitter.com/ponsfrilus/status/1222786610267291648</small>
----
## ssh-copy-id
> <small>**ssh-copy-id** installs an SSH key on a server as an authorized key. Its purpose is to provision access without requiring a password for each login. This facilitates automated, passwordless logins and single sign-on using the SSH protocol.</small>
<small>https://www.ssh.com/ssh/copy-id</small>
----
## Import Keys
```sh=
wget https://github.com/ponsfrilus.keys -O - \
>> /root/.ssh/authorized_keys
```
https://github.com/ponsfrilus/scripts/blob/master/addKeysFromGithub.sh
----

----
## ssh-import-id
**ssh-import-id** - retrieve one or more public keys from a public keyserver and append them to the current user's authorized_keys file (or some other specified file).
----

----
## ssh-import-id
```sh=
$ ssh-import-id gh:ponsfrilus
2020-02-26 17:46:03,853 INFO Authorized key ['2048', 'SHA256:N6/...', 'ponsfrilus@github/10698618', '(RSA)']
2020-02-26 17:46:03,857 INFO Authorized key ['256', 'SHA256:my...', 'ponsfrilus@github/41115620', '(ED25519)']
2020-02-26 17:46:03,858 INFO [2] SSH keys [Authorized]
```
---
# RSA and keys security
<!-- .slide: data-background="https://i.imgur.com/5DUf590.jpg"-->
----
## RSA
> <small>It is now possible to perform chosen-prefix attacks against the SHA-1 hash algorithm for less than USD$50K. For this reason, we will be disabling the "ssh-rsa" public key signature algorithm that depends on SHA-1 by default in a near-future release.</small>
<small>https://www.openssh.com/txt/release-8.2</small>
----
## Not as bad as it sounds...
> <small>The RFC8332 RSA SHA-2 signature algorithms rsa-sha2-256/512. These algorithms have the advantage of using the same key type as "ssh-rsa" but use the safe SHA-2 hash algorithms. These have been supported since OpenSSH 7.2 and are already used by default if the client and server support them.</small>
<small>https://security.stackexchange.com/a/226133</small>
----
## Type of keys (1/2)
* <small>🚨 DSA: It’s unsafe and even no longer supported since OpenSSH version 7, you need to upgrade it!</small>
* <small>⚠️ RSA: It depends on key size. If it has 3072 or 4096-bit length, then you’re good. Less than that, you probably want to upgrade it. The 1024-bit length is even considered unsafe.</small>
<small>https://medium.com/risan/upgrade-your-ssh-key-to-ed25519-c6e8d60d3c54</small>
----
## Type of keys (2/2)
* <small>👀 ECDSA: It depends on how well your machine can generate a random number that will be used to create a signature. There’s also a trustworthiness concern on the NIST curves that being used by ECDSA.</small>
* <small>✅ Ed25519: It’s the **most recommended** public-key algorithm available today!</small>
<small>https://medium.com/risan/upgrade-your-ssh-key-to-ed25519-c6e8d60d3c54</small>
----
## Ed25519
<small>In public-key cryptography, Edwards-curve Digital Signature Algorithm (EdDSA) is a digital signature scheme using a variant of Schnorr signature based on twisted Edwards curves. It is designed to be **faster** than existing digital signature schemes without sacrificing **security**. It was developed by a team including Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang. The reference implementation is **public domain software**.</small>
<small>https://en.wikipedia.org/wiki/EdDSA</small>
<small>https://en.wikipedia.org/wiki/Curve25519</small>
----
## Generating Ed25519 Key
```sh=
ssh-keygen -o -a 100 -t ed25519 \
-f ~/.ssh/id_ed25519 -C "ponsfrilus@gmail.com"
```
----
## Change...
* https://github.com/settings/keys
* https://gitlab.com/profile/keys
----
## Using id_ed25519
```sh=
ssh -i ~/.ssh/id_ed25519 john@198.222.111.33
```
or
``` sh=
$ server: ssh-import-id gh:ponsfrilus
```
---
# Managing multiple ssh keys
<!-- .slide: data-background="https://i.imgur.com/mKRIORn.jpg"-->
----
```
Host myshortname realname.example.com
HostName realname.example.com
IdentityFile ~/.ssh/realname_rsa # private key for realname
User remoteusername
Host myother realname2.example.org
HostName realname2.example.org
IdentityFile ~/.ssh/realname2_rsa # different private key for realname2
User remoteusername
```
<small>https://stackoverflow.com/a/2419609/960623</small>
----

---
```
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
IdentityFile ~/.ssh/id_rsa # Keep any old key files if you want
```
<small>https://stackoverflow.com/a/33228296/960623</small>
----

----
### Why ?
You can instruct ssh to try multiple keys in succession when connecting. Here's how:
```
$ cat ~/.ssh/config
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_rsa_old
IdentityFile ~/.ssh/id_ed25519
# ... and so on
$ ssh server.example.com -v
....
debug1: Next authentication method: publickey
debug1: Trying private key: /home/example/.ssh/id_rsa
debug1: read PEM private key done: type RSA
debug1: Authentications that can continue: publickey
debug1: Trying private key: /home/example/.ssh/id_rsa_old
debug1: read PEM private key done: type RSA
....
[server ~]$
```
<small>https://stackoverflow.com/a/33228296/960623</small>
----
## Demo (1/3)
```sh=
$ ssh-copy-id -i ~/.ssh/id_ed25519.pub nborboen@darsrv6.epfl.ch
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/nborboen/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'nborboen@darsrv6.epfl.ch'"
and check to make sure that only the key(s) you wanted were added.
```
----
## Demo (2/3)
```sh=
$ ssh -i ~/.ssh/id_ed25519.pub nborboen@darsrv6.epfl.ch
Last login: Fri Feb 21 22:49:12 2020 from vpn-253-001.epfl.ch
[nborboen@darsrv6 ~]$
```
----
## Demo (3/3)
```sh=
ssh -vvv nborboen@darsrv6.epfl.ch
OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017
debug1: Reading configuration data /home/nborboen/.ssh/config
debug1: /home/nborboen/.ssh/config line 361: Applying options for *
[...]
debug3: hostkeys_foreach: reading file "/home/nborboen/.ssh/known_hosts"
debug3: record_hostkey: found key type ECDSA in file /home/nborboen/.ssh/known_hosts:14
debug3: record_hostkey: found key type RSA in file /home/nborboen/.ssh/known_hosts:40
debug3: load_hostkeys: loaded 3 keys from darsrv6.epfl.ch
[...]
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:CUIjlIAbzAEMKbJW/Oi254UEgE4WxS2A6FgLIm6Aajo
[...]
debug1: Host 'darsrv6.epfl.ch' is known and matches the ECDSA host key.
debug1: Found key in /home/nborboen/.ssh/known_hosts:14
[...]
debug2: key: /home/nborboen/.ssh/id_ed25519 (0xSSaff74611c0), agent
debug2: key: /home/nborboen/.ssh/id_rsa (0xSSaff7470d70), agent
debug2: key: nborboen@T480s (0xSSaff7473f80), agent
[...]
debug1: Offering public key: ED25519 SHA256:myhFSCXm0rFMAcS1oGJBY1Eba16KXLbcnL9+Wvnsfb8 /home/nborboen/.ssh/id_ed25519
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 60
debug1: Server accepts key: pkalg ssh-ed25519 blen 51
[...]
debug1: Authentication succeeded (publickey).
Authenticated to darsrv6.epfl.ch ([128.178.224.xxx]:22).
[...]
Last login: Fri Feb 21 22:50:20 2020 from vpn-253-001.epfl.ch
[nborboen@darsrv6 ~]$
```
---
# Manage 2 identities with Git
<!-- .slide: data-background="https://i.imgur.com/fIZGO6o.jpg"-->
----
## 1) ssh_config
```sh=
# Company account
Host company
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_company
# Personal account
Host personal
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_personal
```
----
## 2) clone
1. Clone from company account.
`git clone git@company:abc1234/demo.git`
1. Clone from personal account.
`git clone git@personal:abc1234/demo.git`
<small>https://stackoverflow.com/a/38454037/960623</small>
----
## Alternative
Specify sshCommand in repository specific git config file.
```sh=
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
sshCommand = ssh -i ~/.ssh/id_ed25519
[remote "origin"]
url = git@bitbucket.org:user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
```
<small>https://stackoverflow.com/a/51918642/960623</small>
---
# How to send your GIT config while traveling with ssh?
<!-- .slide: data-background="https://i.imgur.com/xNXdhQj.jpg"-->
----
## Example SendEnv .ssh/config
```sh=
Host *
SendEnv GIT_*
```
----
## Example SendEnv client
```sh=
$ cat ~/.profile
...
export GIT_AUTHOR_NAME="Nicolas Borboën"
export GIT_AUTHOR_EMAIL="ponsfrilus@gmail.com"
export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
...
$ env | grep GIT
GIT_COMMITTER_NAME=Nicolas Borboën
GIT_COMMITTER_EMAIL=ponsfrilus@gmail.com
GIT_AUTHOR_NAME=Nicolas Borboën
GIT_AUTHOR_EMAIL=ponsfrilus@gmail.com
```
----
## Example SendEnv Server
```sh=
cat /etc/ssh/sshd_config
[...]
# Allow client to pass locale environment variables
AcceptEnv LANG LC_* GIT_*
[...]
```
----
## Alternative method 1/2
Additionally, ssh reads `~/.ssh/environment`, and adds lines of the format `“VARNAME=value”` to the environment if the file exists and users are allowed to change their environment.
----
## Alternative method 2/2
`man 5 sshd_config /PermitUserEnvironment`
<small>Specifies whether ~/.ssh/environment and environment= options in
~/.ssh/authorized_keys are processed by sshd(8). Valid options are yes, no or a
pattern-list specifying which environment variable names to accept (for example
"LANG,LC_*"). The default is no.</small>
---
# Forward X11
<!-- .slide: data-background="https://i.imgur.com/pzahFgO.jpg"-->
----
X11 forwarding is a mechanism that allows **graphical interfaces** of X11 programs running on a **remote system** to be **displayed on a local** client machine.
----
## How ?
To get X11 forwarding working over ssh, you'll need 3 things in place.
1. Your client must be set up to forward X11 (`ForwardX11`).
1. Your server must be set up to allow X11 forwarding (`xorg`).
1. Your server must be able to set up X11 authentication (`xauth`).
<small>https://unix.stackexchange.com/a/46748/169984</small>
----
## ssh -X
```
-X Enables X11 forwarding. This can also be specified on
a per-host basis in a configuration file.
X11 forwarding should be enabled with caution. Users
with the ability to bypass file permissions on the
remote host (for the user's X authorization database)
can access the local X11 display through the forwarded
connection. An attacker may then be able to perform
activities such as keystroke monitoring.
For this reason, X11 forwarding is subjected to X11
SECURITY extension restrictions by default.
```
----
## Example ForwardX11
```sh=
ssh -X [user@]hostname [command]`
```
or in .ssh/config:
```sh=
Host myshortname realname.example.com
[...]
ForwardX11 yes
[...]
```
---
# Dynamic port forwarding
<!-- .slide: data-background="https://i.imgur.com/ZOgWegA.jpg"-->
----
<small>Specifies a local “dynamic” application-level port forwarding. This works by allocating a **socket to listen to port on the local side**, optionally bound to the specified bind_address. **Whenever a connection is made to this port, the connection is forwarded over the secure channel**, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and **SOCKS5** protocols are supported, and ssh will act as a SOCKS server.</small>
----
## SOCKS
<small>**SOCKS** is an Internet protocol that **exchanges network packets between a client and server through a proxy server**. SOCKS5 optionally provides authentication so only authorized users may access a server. Practically, a SOCKS server proxies TCP connections to an arbitrary IP address, and provides a means for UDP packets to be forwarded.</small>
<small>https://en.wikipedia.org/wiki/SOCKS</small>
----
## Use case
Access a remote ressource that is only accessible locally on the remote server, e.g. [adminer](https://www.adminer.org/) in a Docker container that don't have any port binded.
----
## SOCKS config
```
$ ssh -D [bind_address:]port [user@]hostname [command]
```
or
```sh=
Host hostname
DynamicForward 3333
```
----
## Proxy config
Once connected with dynamic forward, you have to acquaint your proxy configuration with the same port. Note that [Foxy Proxy](https://getfoxyproxy.org/) is a convenient way to do it, and it support multiple configuration based on hosts.
---
# SSHFS
<!-- .slide: data-background="https://i.imgur.com/JwPluXp.jpg"-->
----
<small>In computing, **SSHFS** (SSH Filesystem) is a filesystem **client** to **mount** and interact with directories and **files** located on a **remote server** or workstation over a **normal ssh** connection. The client interacts with the remote file system via the **SSH File Transfer Protocol (SFTP)**, a network protocol providing file access, file transfer, and file management functionality over any reliable data stream that was designed as an extension of the Secure Shell protocol (SSH) version 2.0.</small>
<small>https://en.wikipedia.org/wiki/SSHFS</small>
----
## man sshfs
<small>SSHFS (Secure SHell FileSystem) is a file system for Linux (and other operating systems with a FUSE implementation, such as Mac OS X or FreeBSD) **capable of operating on files on a remote computer using just a secure shell** login on the remote computer. On the local computer where the SSHFS is mounted, the implementation makes use of the **FUSE (Filesystem in Userspace)** kernel module. The practical effect of this is that the **end user can seamlessly interact with remote files** being securely served over SSH just as if they were local files on his/her computer. On the remote computer the SFTP subsystem of SSH is used.</small>
----
## sshfs
* Mount
```shell=
$ sshfs [user@]host:[dir] mountpoint [options]
```
* Umount
```shell=
$ fusermount -u mountpoint
```
---
# SSH Tunneling
<!-- .slide: data-background="https://i.imgur.com/Oz7RsPC.jpg"-->
----
https://unix.stackexchange.com/questions/213213/difference-between-local-port-forwarding-and-dynamic-port-forwarding
----
SSH tunneling (also called SSH port forwarding)
----

https://www.ssh.com/ssh/tunneling
----
## Reverse SSH tunneling
<small>Reverse SSH tunneling allows you to **use** that **established connection** to set up a new connection from your local computer **back to the remote computer**.</small>
---
<!-- this slide is intentionally left blank -->
<!-- .slide: data-background="https://i.imgur.com/LiPiXwt.jpg"-->
---
# It's your turn
<!-- .slide: data-background="https://i.imgur.com/MaU3ByI.jpg"-->
----
## Exercice 1
1. `ssh username@10.95.16.9` → gaspar password
1. create relevant ssh_config entry, using `sivm0030` and `fsdtest` as alias
1. add your ssh key using `ssh-copy-id` or `ssh-import-id`
1. connect to `sivm0030` without password
----
## Exercice 2
1. add `ForwardX11 yes` to this host's ssh config
1. test with `xeyes` or `firefox -no-remote`
----
## Exercice 3
1. add `DynamicForward 3333` to this host's ssh config
1. configure your browser's SOCKS5¹ proxy or use [Foxy Proxy](https://getfoxyproxy.org/)
1. access the server's localhost:1337 — if you see a cat's gif you're good
<small>¹Firefox disable localhost and 127.0.0.1 by default, you would have to use 127.0.0.2 through Firefox</small>
----
## Exercice 4
1. visit https://tremplin.epfl.ch/ssh.html
1. create a SSH tunnel to 10.95.16.9:
`ssh -L 2222:10.95.16.9:22 tremplin.epfl.ch -l YourSciper`
1. connect to 10.95.16.9 using the port 2222
`ssh -p 2222 localhost -l username`
1. close the terminal with the SSH tunnel
1. confirm that your are still connected to the server
----
## Exercice 5
1. ensure `sshfs` installed
1. create a folder to use as mountpoint (e.g. `/tmp/sshfs`)
1. mount your server's home folder in it:
`sshfs fsdtest:~ /tmp/sshfs`
1. observe to connectivity between your machine `/tmp/sshfs` and your `$HOME` on the server
---
# Bonus
<!-- .slide: data-background="https://i.imgur.com/jqEzubH.jpg"-->
----
## whoami.fillippo.io

whoami.fillippo.io
----
## Idea instructions
[](https://idea-instructions.com/public-key/)
---
# References
* https://stackoverflow.com/questions/2419566/best-way-to-use-multiple-ssh-private-keys-on-one-client
* https://medium.com/risan/upgrade-your-ssh-key-to-ed25519-c6e8d60d3c54
* https://twitter.com/FiloSottile/status/1229093553269362689
* https://infosec.mozilla.org/guidelines/openssh.html
---
# About these slides
Done on https://hackmd.io (which uses [reveal.js](https://revealjs.com/)).
Slides's background images are from https://www.pexels.com/@steve
Slides URL's https://hackmd.io/@ponsfrilus/SSH
---
# That's all folks
<!-- .slide: data-background="https://i.imgur.com/Yk1fxwI.jpg"-->
{"metaMigratedAt":"2023-06-15T04:33:39.851Z","metaMigratedFrom":"YAML","title":"Fondamentals: SSH","breaks":true,"description":"Fondamentals tools - SSH","image":"https://avatars.githubusercontent.com/u/176002?s=96","slideOptions":"{\"transition\":\"convex\",\"theme\":\"black\",\"progress\":true,\"slideNumber\":true,\"transitionSpeed\":\"fast\"}","contributors":"[{\"id\":\"98cf1d10-5049-49ca-9160-3f2e67fc1067\",\"add\":33469,\"del\":12501}]"}