her.esy.fun/src/posts/0006-modern-irc/index.org

474 lines
14 KiB
Org Mode
Raw Normal View History

2019-10-15 19:26:47 +00:00
#+TITLE: Modern IRC
#+SUBTITLE: In 2019, IRC is still the best.
2019-10-04 19:41:42 +00:00
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-10-19 Sat]
2019-10-15 19:26:47 +00:00
#+KEYWORDS: self-hosting, chat, irc
#+DESCRIPTION: How to modernize IRC
2019-10-04 19:41:42 +00:00
#+OPTIONS: auto-id:t
#+begin_notes
2019-10-19 17:13:18 +00:00
tl;dr: Why and how to have modern and respectful chat system with IRC.
2019-10-15 19:26:47 +00:00
After reviewing and testing many different chat solutions the clear winner
2019-10-19 17:13:18 +00:00
is IRC. More precisely a group of different softwares togethers:
- IRC
- ZNC (with replay module and palaver module)
- weechat (with replay script)
- thelounge
- Palaver (for iOS mobile).
2019-10-04 19:41:42 +00:00
#+end_notes
2019-10-15 19:26:47 +00:00
How to chat in 2019? Certainly with slack, or via a social media app in the
browser or mobile phone app.
How geeks should chat in 2019?
2019-10-19 17:13:18 +00:00
To answer this question here is my opinion after having tried many
2019-10-15 19:26:47 +00:00
different chat solutions[fn:tries].
2019-10-19 17:13:18 +00:00
Here are the feature I think a modern solution should have:
2019-10-15 19:26:47 +00:00
1. *terminal client* or *terminal-like UI* (in emacs for example).
All modern UI looks cool for screenshots, but if you are going to use it
a lot, you will prefer density over good looking.
Most app, web app are terrible related to information by number of pixel
ratio.
2019-10-16 12:26:26 +00:00
2. *multi-platform*: If you do not have a terminal at hand (or emacs) then,
2019-10-15 19:26:47 +00:00
you should be able to get your message on your phone or via a web
interface for portability.
3. *self-hosted*: you should control your data, your history, your logs,
the encryption methods, etc...
4. *teams* and *direct messages*
5. *notifications*, I tend to control those a lot, but a small private team
chat is one of few exception where you generally want to be notified.
2019-10-16 12:26:26 +00:00
6. *Frugal*. Really, we have a responsibility to do our best not to consume
2019-10-15 19:26:47 +00:00
more resources than we really need.
Chat should be about TEXT, not images, not videos, not presentations and
PDF.
7. Refuse anti-features: show when someone is typing, show when someone
as read your message, etc... Those functionality are in fact increasing
social insecurity and forces you to answer sooner instead of really
taking the time to answer correctly.
8. Use free software (not just open source software).
2019-10-16 12:26:26 +00:00
I am quite disappointed by /modern/ chat applications.
2019-10-15 19:26:47 +00:00
Their major problems are:
2019-10-19 17:13:18 +00:00
- *resource-heavy*; most those client applications (slack, gitter, riot,
2019-10-16 12:26:26 +00:00
mattermost, etc...) easily consume more than 300MB of RAM.
Most of the time those clients are all electron app.
2019-10-19 17:13:18 +00:00
- *not private*; most solution do not encrypt your conversations.
Even if using encryption mechanism and you trust your client, and you
will still reveal your social network topology.
- *anti-minimalist*; I want dense /text/.
2019-10-16 12:26:26 +00:00
I do not want:
+ emojis,
+ images,
+ animations (gif or videos),
+ HTML/Markdown display
2019-10-19 17:13:18 +00:00
- *manipulative*; they try very hard to optimize engagement.
2019-10-16 12:26:26 +00:00
This is generally achieved through FOMO[fn:FOMO] and social anxiety
manipulations.
A few examples:
+ show when someone is writing a message
+ show when someone has read a message,
+ get notified about missed messages,
+ get a "top messages you missed",
+ etc...
2019-10-19 17:13:18 +00:00
- *Prepare to EEE[fn:eee]*:
2019-10-16 12:26:26 +00:00
Most of those "modern" solution are a all-in-one solution, server +
clients with generic + specific features.
That way, some feature will be only possible in their client or that will
push concurrent app developers to follow the pace of new features.
2019-10-19 17:13:18 +00:00
** Digression
:PROPERTIES:
:CUSTOM_ID: digression
:END:
The /manipulative/ part is quite important to me.
Many users appeart to ask for those "features".
I think this is beacause most of those people should take the time to
reflect about the real plus value of those features vs their price.
As it is stated in Digital Minimalism[fn:dm], those feature are not the
real reason you use it.
I think this is an instance of the recent software development:
The idea that software MUST evolve and change.
Add as much new features as possible, instead of striving for simplicity,
stability and security.
We pass too much time asking about the how and forgetting about the why?
I would rather prefer a system that does not evolve much but study the real
full impact of adding a new feature to it.
And I think some software should be considered *finished* (like TeX).
2019-10-16 12:26:26 +00:00
Would that feature be a full total net positive for everyone?
Or is there a price to pay? The price is generally the size and complexity
of the project, that will make it bigger, slower, harder to manipulate,
install, interact-with.
[fn:eee] [[https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish][Embrace, extend, and extinguish]].
[fn:dm] http://www.calnewport.com/books/digital-minimalism/
** About failed attempts :PROPERTIES: :CUSTOM_ID: different-tries
2019-10-15 19:26:47 +00:00
:PROPERTIES:
2019-10-16 12:26:26 +00:00
:CUSTOM_ID: about-failed-attempts--properties---custom-id--different-tries
:END:
2019-10-15 19:26:47 +00:00
:END:
- Matrix: I've used Matrix, and in fact it was really good except; the
server is written in python and is clearly not frugal at all.
Also I wanted to delete most of the history in the DB, and it was
impossible to find a working documentation explaining how to do that
correctly and easily (I'm not even sure this is possible).
You can easily remove some channels history from the DB, but doing the
opposite, keeping the history only of some channel and removing all others
doesn't appear to be easy.
- Mattermost: I've tried to install mattermost, to install it, there is
no package, you need to start a shell script as root that will erase and
change your nginx configuration.... Seriously...
- Rocket.chat, ho.... a nice word about the difference between community
version and pro version... no thank you. I prefer something sustained by
free software standards.
- I tried XMPP, it was OK. But the clients weren't really good, I could
have used bitlbee, the installation looked more complex than IRC.
2019-10-04 19:41:42 +00:00
Finally, IRC + ZNC with replay module is the winner.
2019-10-15 19:26:47 +00:00
It was the easiest and best solution.
2019-10-04 19:41:42 +00:00
2019-10-12 14:09:41 +00:00
1. it works
2019-10-15 19:26:47 +00:00
2. it is Free Software
2019-10-12 14:09:41 +00:00
3. it is frugal
2019-10-15 19:26:47 +00:00
4. it is old
5. it is minimalist
6. it is feature complete for a small team chat.
2019-10-16 12:26:26 +00:00
[fn:FOMO] Fear Of Missing Out
2019-10-15 19:26:47 +00:00
[fn:tries] Here is a list of the chatting solutions I used for some time
2019-10-16 12:26:26 +00:00
and finally abandoned (I certainly forgot a few ones):
2019-10-15 19:26:47 +00:00
- slack
- matrix (self-hosted)
- keybase
- discord
- gitter
- XMPP (both hosted by a 3rd party and self-hosted)
- IRC ← the winner
2019-10-12 14:09:41 +00:00
2019-10-07 15:54:11 +00:00
* Tutorial
:PROPERTIES:
:CUSTOM_ID: tutorial
:END:
2019-10-19 17:13:18 +00:00
Here is how to have a great private self-hosted IRC server to share with a
small group of people.
If this appear to be too much work for you, you should simply use a service
that host a znc bouncer for you (I found some apparently free services
doing that) and find an IRC server allowing you to create some private
channel.
2019-10-07 15:54:11 +00:00
** Self Host
:PROPERTIES:
:CUSTOM_ID: self-host
:END:
2019-10-16 15:03:04 +00:00
You might use an external IRC server.
But it is a lot safer to self-host it.
Self-hosting might not be easy if you are not familiar about how to do
that.
1. buy a domain name
2. buy a machine (VPS, baremetal, host it at your home)
3. configure the DNS for your domaine name go to your machine
4. configure letsencrypt to support wildcard hostnames.
5. know how to create reverse proxy
I couldn't find a nice resource to link to with all those details.
This is certainly a call to write such article myself.
*** Create a reverse proxy with nginx
:PROPERTIES:
:CUSTOM_ID: create-a-reverse-proxy-with-nginx
:END:
This is how I create new reverse proxy with nginx using a template:
2019-10-19 20:37:25 +00:00
[[./reverse-proxy-template.m4][reverse-proxy-template.m4]].
2019-10-19 20:37:25 +00:00
#+begin_src m4 :exports none :tangle reverse-proxy-template.m4
# Nginx configuration
server {
server_name SUB.DOMAIN;
access_log /var/log/nginx/SUB()_ssl_access.log;
error_log /var/log/nginx/SUB()_ssl_error.log;
# # access restricted
# auth_basic "Admin restricted";
# auth_basic_user_file /etc/nginx/htpasswd;
listen *:443 ssl;
listen [::]:443 ssl;
server_tokens off;
## SSL
ssl on;
ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem; # managed by Certbot
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
## [Optional] Enable HTTP Strict Transport Security
## HSTS is a feature improving protection against MITM attacks
## For more information see: https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
location / {
proxy_pass http://127.0.0.1:PORT;
gzip off;
proxy_redirect off;
## Some requests take more than 30 seconds.
proxy_read_timeout 30s;
proxy_connect_timeout 30s;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Client-Verify SUCCESS;
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-SSL-Subject $ssl_client_s_dn;
proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
}
}
## Redirects all HTTP traffic to the HTTPS host
server {
## In case of conflict, either remove "default_server" from the listen line below,
## or delete the /etc/nginx/sites-enabled/default file.
listen 0.0.0.0:80;
listen [::]:80;
server_name SUB.DOMAIN;
server_tokens off; ## Don't show the nginx version number, a security best practice
return 301 https://$http_host$request_uri;
access_log /var/log/nginx/SUB.DOMAIN()_access.log;
error_log /var/log/nginx/SUB.DOMAIN()_error.log;
}
#+end_src
2019-10-19 20:37:25 +00:00
That I use with the following script: [[./new-reverse-proxy.sh][new-reverse-proxy.sh]]
2019-10-19 20:37:25 +00:00
#+begin_src bash :tangle new-reverse-proxy.sh
#!/usr/bin/env zsh
(($#<3)) && {
print "usage: $0:t SUB DOMAIN PORT"
exit 1
} >&2
SUB="$1"
DOMAIN="$2"
PORT="$3"
m4 -D SUB=$SUB -D DOMAIN=$DOMAIN -D PORT=$PORT reverse-proxy-template.m4 > $SUB.$DOMAIN
#+end_src
The script will generate a reverse proxy nginx conf that I put in
=/etc/nginx/sites-available/= and I link it in =/etc/nginx/sites-enabled=.
2019-10-07 15:54:11 +00:00
** Install/configure ngircd
:PROPERTIES:
:CUSTOM_ID: install-configure-ngircd
:END:
2019-10-16 15:03:04 +00:00
There are multiple IRC server.
I gave my preference to [[https://github.com/ngircd/ngircd][ngircd]] because it appeared lightweight, easy to
install and configure.
So use your preferred package manager to install it:
#+begin_src
sudo apt-get install ngircd
#+end_src
Configure the =/etc/ngircd/ngircd.conf= file.
I only show the really interesting lines for a private small IRC for a team.
#+begin_src src
[Global]
Name = irc.your.domain
Info = My Incredible IRC
Password = privateIRCSecretPassword
[Options]
# prevent channel creation
AllowedChannelTypes =
[SSL]
Certfile = /etc/letsencrypt/live/your.domain/fullchain.pem
Keyfile = /etc/letsencrypt/live/your.domain/privkey.pem
Ports = 6667,9999
[Channel]
# predefined channel
Name = #general
Topic = Main team channel
MaxUsers = 23
[Channel]
Name = #status
Topic = Status update channel
MaxUsers = 23
#+end_src
2019-10-07 15:54:11 +00:00
** Install/configure ZNC
:PROPERTIES:
:CUSTOM_ID: install-configure-znc
:END:
2019-10-16 15:03:04 +00:00
Install ZNC from sources or via your package manager.
I choose sources. Choose the latest version if you can.
#+begin_src
> wget https://znc.in/releases/archive/znc-1.7.5.tar.gz
> tar xzf znc-1.7.5.tar.gz
> cd znc-1.7.5
> mkdir build
> cd build
> make
> make install
#+end_src
Then create your config file for example via:
#+begin_src
> znc --makeconf
#+end_src
For the question, keep buffers after replay, you should certainly answer
yes.
To use znc web interface behind an nginx reverse proxy:
#+begin_src conf
<Listener listener0>
AllowIRC = false
AllowWeb = true
Host = localhost
IPv4 = true
IPv6 = false
Port = 10001
SSL = false
URIPrefix = /
</Listener>
<Listener listener1>
AllowIRC = true
AllowWeb = false
IPv4 = true
IPv6 = true
Port = 10002
SSL = true
URIPrefix = /
</Listener>
#+end_src
Now you can put your znc behind a reverse proxy.
2019-10-16 15:03:04 +00:00
*** Playback module
:PROPERTIES:
:CUSTOM_ID: playback-module
:END:
#+begin_src
> cd ~/.znc/modules
> wget ...../playback.cpp
> znc-buildmod playback.cpp
#+end_src
Should create a =playback.so=.
*** Palaver push module
:PROPERTIES:
:CUSTOM_ID: palaver-push-module
:END:
#+begin_src
> git clone ... znc-palaver
> cd znc-palaver
> znc-buildmod palaver.cpp
> cp palaver.so ~/.znc/modules/
#+end_src
That's it.
The major modernizer of IRC are here in ZNC.
2019-10-07 15:54:11 +00:00
** Install/configure clients
:PROPERTIES:
:CUSTOM_ID: install-configure-clients
:END:
*** weechat
:PROPERTIES:
:CUSTOM_ID: weechat
:END:
1. add the [[https://weechat.org/scripts/source/zncplayback.py.html/][weechat znc playback script]]
2. add the default server capabilities
#+begin_src irc
/set irc.server_default.capabilities "account-notify,away-notify,cap-notify,multi-prefix,server-time,znc.in/server-time-iso,znc.in/self-message,znc.in/playback
#+end_src
3. add the server for your networks:
#+begin_src irc
/server add zncnetwork znc.my.domain/6697 -ssl -username=username/zncnetwork -password=password -autoconnect
/connect zncnetwork
#+end_src
More details here: https://wiki.znc.in/Weechat
*** thelounge
:PROPERTIES:
:CUSTOM_ID: thelounge
:END:
Here are the infos for installing it.
https://thelounge.chat/docs/install-and-upgrade
You can use my reverse proxy scripts to put the lounge behind a reverse
proxy from your host. So you'll be able to reach =thelounge.my.domain=.
2019-10-07 15:54:11 +00:00
*** Palaver
:PROPERTIES:
:CUSTOM_ID: palaver
:END:
Using palaver should be straightfoward.
Here is its website: https://palaverapp.com
I previously used the app mutter, but it appears to be deprecated and has a lot of
bugs since the iOS 13 update.
2019-10-12 14:09:41 +00:00
* Bonus
:PROPERTIES:
:CUSTOM_ID: bonus
:END:
** No brainer upload file
:PROPERTIES:
:CUSTOM_ID: no-brainer-upload-file
:END:
I made an image uploader inspired by the image uploader example of the
Yesod web framework.
It is only one single self-executable file + one css and jquery.
The only dependency is [[https://docs.haskellstack.org/en/stable/README/][stack]].
So to install it:
1. install [[https://docs.haskellstack.org/en/stable/README/][stack]]
2. create an nginx reverse proxy protected with basic-auth
3. share the creds to your team mates
4. start the script, and enjoy