IRC
10 Oct 2015 • Leave Comments- ABCs
- Style
- Security
- server_default
- Server
- NickServ
- Identification
- Unaffilicated Cloak
- proxy - Tor
- Relay
- Systemd user Unit
- Troubleshooting
Simple Authentication and Security Layer (SASL) is a method that simplify identification to NickServ as the first step after connecting to IRC servers, before anything else happens. To connect to freenode using Tor, SASL is required. In this post, I will take Weechat and Freenode for example.
ABCs
-
Conncet through WebChat on browser.
Just fill in nick and channel names on freenode webchat. HTTPS (ssl) establish a secure connection IRC server compared to HTTP.
By Webchat, we cannot require other services.
-
Connect in the clear.
Similar to Webchat, the clear way connects directly without proxy or nick reservation (by NickServ).
Should provide IRC hostname (chat.freenode.net) and port (6697) which are implicit in Webchat (webchat.freenode.net and 80).
After connection, join a channel to talk.
- Connect through Clients (Weechat Irssi etc.).
-
Nickserv - register/identify
Reserve and identify your nick name.
-
SASL authentication
Automatic identification on connection by SASL. Weechat SASL supports different authentication mechanisms:
- plain: plain text file password (default)
- ecdsa-nist256p-challenge: challenge with public/private key
- external: self-signed SSL certificate
- …
- Connect with proxy (i.e. Tor).
-
BNC (i.e. ZNC), or Weechat relay protocol.
Weechat relay supports IRC protocol as well (to be compatibile with other IRC clients).
Style
jim@laptop ~ $ weechat
-
iset
/script search iset Alt + i /save /iset
/save after changes. WeeChat also saves your up-to-date configuration any time you exit the program.
Script iset is decpreated and please use built-in script fset instead.
-
Some specific server commands (i.e. /ns) are not standard and cannot be recoginized by IRC client.
irc.network.send_unknown_commands on
-
This will close the buffer (or called tab) immediately when parting a channel.
irc.look.part_closes_buffer on
-
By default, server and core buffers are merged together. Use
Ctrl+x
to tear apart or:irc.look.server_buffer independent
Security
-
SSL
irc.server_default.ssl on irc.server_default.ssl_verify on irc.server_default.sasl_mechanism external
The client verify the server certificate and also the server needs to verify the client certificate - mutual authentication!
-
Turn off ctcp to prevent others from querying IRC client information.
*ctcp* "" *ctcp* off
-
Message
irc.server_default.msg_part "" irc.server_default.msg_quit ""
server_default
Some extra optional default server arguments.
irc.server_default.nicks ""
irc.server_default.username ""
irc.server_default.realname ""
Server
/server add freenode chat.freenode.net/6697 -ssl
/set irc.server.freenode.nicks "username"
/connect freenode
Check server_default section of ~/.config/weechat/irc.conf. Common default server options can be set here (i.e. irc.server_default.ssl).
NickServ
NickServ allows users to register nicks on IRC servers. Different IRC servers support different set of NickServ commands. We can check by /msg nickserv help
beforehand. Make sure you are connected to IRC server with your desired nick by /nick new-nick command.
Don't execute the following commands in a channel tab, otherwise sensitive information (i.e. password) might be disposed and sniffed. All IRC commands are case-insensitive.
Take Freenode for example:
-
/msg NickServ REGISTER <password> youremail@example.com
In Weechat, the pasword youremail@example.com part will be displayed as asterisks. But don't worry as long as you put a space between password and youremail@example.com.
After this command, Weechat will show password and youremail@example.com as plain text. IRC server uses the current nick (username) as the account name. So username is both the nick and account name registered on freenode. This special nick is called primary nick.
In a while, you will receive an email, from which you should copy the verification command to complete the registration process:
-
/msg nickserv confirm <temporary-code>
or/msg nickserv verify register <username> <temporary-code>
This temporary-code is only for account registration confirm.
Now, account name username has just one nick username associated on Freenode server, no one else can use nick username unless the correct password is identified (talked later on).
OFTC server does need this extra confirmation step.
-
/msg NickServ SET HIDE EMAIL ON
To keep your email address private, rather than displaying it publicly, mark it as hidden.
For OFTC, it's /msg nickserv set private on.
-
Group more nicks account.
A Freenode account can reserve multiple nicks. First switch to a new nick and then group it to our account (as long as that nick is not reserved by others). Grouping nicks in this way gives you the benefit of having all your nicks covered by the same unaffiliated cloak. The default group name is the account name, namely username.
# switch to nick "username_" /nick username_ /msg nickserv group
To remove a nick from your account:
/nick username /msg nickserv ungroup username_
-
/reconnect
It will prompt like username is registered… you must identify yourself…. To identify yourself as nick username:
/msg NickServ identify username <password>
Identification
Manually Identification
If you don't configure SASL, then you have two choices:
-
Manual identification after connection to server as above.
/reconnect freenode /msg NickServ identify username <password> # freenode /msg NickServ identify <password> username # oftc
-
Use freenode.command to run identify.
irc.server.freenode.command "/msg NickServ identify username <password>"
freenode.command runs a command automatically once connected to the server.
SASL plain scheme
OFTC disallow this scheme.
irc.server.freenode.sasl_mechanism plain
-
set irc.server.freenode.sasl_username username
The username can be any one of your grouped nicks. But usually the primary nick (namely the account name) is used.
-
/secure set freenode <password>
Password will be recorded in ~/.config/weechat/sec.conf.
-
irc.server.freenode.sasl_password "${sec.data.freenode}"
Tell weechat where to get the password.
-
irc.server.freenode.sasl_fail disconnect
If SASL auth fail, disconnect.
SASL external scheme
-
irc.server.freenode.sasl_mechanism external
As long as sasl_mechanism is changed to external, sasl_username and sasl_password setting won't take effect.
-
irc.server.freenode.ssl_cert "%h/ssl/freenode.pem"
We should generate a self-signed X509 certificate before
/reconnect
.
irc.pem
OpenSSL is a cryptography toolkit implementing the SSL/TLS protocols and related cryptography libraries. Virtually, almost any packages using SSL/TLS require OpenSSL support, OpenSSH and Firefox (HTTPS) included.
The openssl program is a command line tool from OpenSSL, providing various cryptography functions. In this post, it will used to genrate self-signed X509 certificate.
jim@laptop ~ $ openssl req -newkey rsa:4096 -nodes -keyout irc.pem -sha256 -x509 -days 365 -out irc.pem -subj "/C=US/ST=NewYork/L=NewYork/O=UST/OU=CS/CN=irc" -addext "subjectAltName = DNS:irc, DNS:weechat, DNS:127.0.0.1"
jim@laptop ~ $ mkdir -p ~/.config/weechat/ssl
jim@laptop ~ $ mv irc.pem ~/.config/weechat/ssl/
- req: certificate request and certificate generating utility.
- nodes: no DES encryption. The RSA private key won't be encrypted by DES.
- keyout: the private key file.
- sha256: the digest to sign certificate.
-
out: the certificate file.
The keyout and out specify the same output file name, which means private key and certificate will be merged automatically.
- subj: certificate Subject field. If not provided on command line, openssl will prompt for user input.
Nick and Certificate Association
To achieve certificate authentication, we should add the certificate's fingerprint to NickServ on freenode server
Get the SHA512 fingerprint.
jim@laptop ~ $ man x509
jim@laptop ~ $ openssl x509 -noout -text -sha512 -fingerprint -in irc.pem
Add the fingerprint:
/whois nick
/msg nickserv cert list
/msg nickserv cert add/del [sha1]
/reconnect
The fingerprint value can be ommited and NickServ on the server will automatically calculate the value.
Finally reconnect to identify nick by SASL external. You can see a line:
gnutls: sending one certificate
during connection. Run /whois nick to see:
has client certificate fingerprint:
Renew certificate
Upon expiration, we need to renew the certificate. Acutally, renewing is to create a new certificate herein.
# Extract private key from certification file (PEM)
~ # openssl rsa -in irc.pem -out irc.key
# Extract public certificate from certification file (PEM)
~ # openssl x509 -in irc.pem -out irc.crt
# Converts the certificate into a certificate request (PEM)
~ # openssl x509 -x509toreq -in irc.crt -out irc.csr -signkey irc.key
# Create a new certification for one year
~ # openssl x509 -req -days 365 -in irc.csr -out irc.crt.new -signkey irc.key
# Concatenate the new certificate and original key
~ # cat irc.crt.new irc.key > irc.pem.new
# Chceck validity
~ # openssl x509 -noout -text -in irc.pem.new
Remember to add the new certificate's fingerprint to IRC server and del the old one.
Unaffilicated Cloak
- Unaffiliated Cloak is to hide your IP from IRC channels.
-
To obtain a cloak, just join the official
#freenode
channel, ask for one there and reconnect.When channel staff notices your request, you might get cloaked. Unaffiliated Cloak applies to all channels on Freenode server.
-
To get a cloak on OFTC is much easier:
/msg nickserv SET CLOAK ON
The above method is now deprecated! Freenode automatically turns on cloak (vHost) for every account. Just run command /msg HOSTSERV ON
. Checking by /whois <username>
. Before and after:
# before
(~weechat@joseon-eldv4c.jnih.mqbr.vquou2.IP): weechat
# after
(~weechat@joseon/user/username): weechat
proxy - Tor
Suppose you would like to connect to IRC server by proxy, how to set?
-
Add proxy
/proxy add tor socks5 127.0.0.1 9050
This will tell Weechat that a proxy named 'tor' is added.
-
Server copy
Suppose we find Tor proxy is troublesome someday, updates to current server must be restored. To ease configuration, issue the following command:
/server copy freenode freenode-tor
Update freenode-tor configuration instead.
-
Enable proxy for IRC server
/set irc.server.freenode-tor.proxy tor
-
However Freenode does not allow Tor connection to chat.freenode.net.
The server hostname should be changed to hidden url freenodeok2gncmy.onion while keeping the original port.
/set irc.server.freenode-tor.addresses freenodeok2gncmy.onion/6697
-
Onion certificate.
Cannot wait to reconnect? Yeah, me too. The server certificate cannot be verified since onion url is not certified by almost all CAs.
gnutls: the hostname in the certificate does NOT match "freenodeok2gncmy.onion"
Currently, only a few onion url is signed by digicert.
The solution is maully trust fetched certificates in which though the hostname is freenode.net instead of freenodeok2gncmy.onion.
When connected to chat.freenode.net, Weechat usually receive three certificates with their SHA-1 fingerprints listed. Collect those fingerprints and assign to:
/set irc.server.freenode-tor.ssl_fingerprint fp1,fp2,fp3,...
Alternatively we can turn off certificate verification:
/set irc.server.freenode-tor.ssl_verify off
If IRC client supports key pinning, we can choose to trust freenode's public key fingerprint instead certificate's fingerprint which benefits us in that the former keep consistent while the later varies in accord with the real freenode server you connect to. Unfortunately, Weechat does not.
If Weechat throws errors like:
gnutls: peer's certificate is NOT trusted
gnutls: peer's certificate issuer is unknown
Please check whether
weechat.network.gnutls_ca_file
is correctly set. On Centos, it should be /etc/pki/tls/certs/ca-bundle.crt; but on archlinux, it should be /etc/ssl/certs/ca-certificates.crt.Recently, freenode Tor servers do not report certificate fingerprint anymore. We can manually print fingerprint by:
~ $ torify gnutls-cli --tofu freenodeok2gncmy.onion:6697 --print-cert | openssl x509 -noout -text -sha256 -fingerprint -in /dev/stdin ~ $ sed 's/://g' <<< "fingerprint delimited by colons"
Relay
To preserve or share IRC message, we can use Bounced Network Connection (BNC) like ZNC. ZNC allows connections from different end users and relay message for each of them.
To simplify the setup, we can use the standard IRC relay and its extended version - weechat relay. Weechat supports both the weechat relay and the standard IRC relay.
If you add a standard IRC relay in Weechat, you can connect to it with any IRC client like HexChat, Irssi etc. The weechat relay runs over Websocket and only allows connections from clients that support Websocket like glowing-bear or Weechat android. However, you can not connect to a weechat relay by weechat installed from Linux package manager!
This section demonstrates the following schema:
- Create a weechat relay instance on a remote server, bound to loopback.
- Nginx as a reverse proxy.
- Glowing-bear or Weechat-android as the front-end client.
Weechat Relay
-
Add relay
/relay add ipv4.weechat 9000 # plaintext relay without SSL /set relay.network.bind_address "127.0.0.1" /set relay.network.password MY-RELAY-PASSWORD /set relay.network.max_clients 3
Nginx Reverse Proxy
-
Nginx HTTPS sample
server { listen 80; ... # enforce https return 301 https://$server_name$request_uri; } server { ... ssl_certificate "/etc/letsencrypt/live/irc.example.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/irc.example.com/privkey.pem"; ....
-
Add nginx proxy
# Set connection header based on upgrade header map $http_upgrade $connection_upgrade { default upgrade; '' close; } # Protect from brute force attack limit_req_zone $binary_remote_addr zone=weechat:10m rate=5r/m; server { listen 80; server_name irc.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name cloud.example.com; ssl_certificate "/etc/letsencrypt/live/irc.example.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/irc.example.com/privkey.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location /weechat { proxy_pass http://127.0.0.1:12545; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_header; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 3600; limit_req zone=weechat burst=1 nodelay; } }
Direct Relay
Acutally, we can connect to the weechat relay directly.
Create a SSL relay and configure as below.
relay.network.max_clients integer 5
relay.network.password string "password"
relay.network.ssl_cert_key string "%h/ssl/irc.pem"
relay.port.ssl.irc integer 12345
Run /relay sslcertkey
to load the cert and key without restart.
Connect to Relay
irc.server.ora1.addresses string "1.2.3.4/12345"
irc.server.ora1.password string "password"
irc.server.ora1.sasl_mechanism integer plain
irc.server.ora1.ssl boolean on
irc.server_default.ssl_verify boolean on
irc.server.ora1.ssl_fingerprint string "<sha512>"
We pin the relay's cert fingerprint for SSL verification.
Systemd user Unit
We can create a systemd user unit to start launch Weechat in headless mode.
Create user unit file ~/.config/systemd/user/weechat-headless.service as bellow.
[Unit]
Description=A headless WeeChat client and relay service
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/weechat-headless --daemon
[Install]
WantedBy=default.target
Enable and start user unit.
~ $ systemctl --user daemon-reload
~ $ systemctl --user enable weechat-headless.service
~ $ systemctl --user start weechat-headless.service
~ $ systemctl --user status weechat-headless.service
If something wrong, we can send signal SIGHUP to the headless process.
~ $ kill -HUP <pid>
Troubleshooting
If it reports "unable to load plugin", please install the optional dependencies.
│22:49:38 =!= | Error: unable to load plugin
│ | "/usr/lib/weechat/plugins/spell.so": libaspell.so.15:
│ | cannot open shared object file: No such file or
│ | directory
│22:49:38 =!= | If you're trying to load a script and not a C plugin,
│ | try command to load scripts (/perl, /python, ...)
│22:49:38 =!= | Error: unable to load plugin
│ | "/usr/lib/weechat/plugins/tcl.so": libtcl.so: cannot
│ | open shared object file: No such file or directory
│22:49:38 =!= | If you're trying to load a script and not a C plugin,
│ | try command to load scripts (/perl, /python, ...)
│22:49:38 =!= | Error: unable to load plugin
│ | "/usr/lib/weechat/plugins/ruby.so": libruby.so.2.7:
│ | cannot open shared object file: No such file or
│ | directory
│22:49:38 =!= | If you're trying to load a script and not a C plugin,
│ | try command to load scripts (/perl, /python, ...)