如何设置您自己的 IRC 网络
Charybdis 自 2021 年起不再维护;所有开发工作已转移到 solanum。(讨论) |
本文档旨在帮助您使用 Alpine Linux 设置您自己的 IRC 网络。
我们将配置两个 IRC 守护进程和一个简单的 ajax webirc 客户端。
IRC 守护进程将协同工作,共享频道、用户和其他信息。
从 Charybdis 的角度来看,此配置称为 “集群”,但不应将此词理解为通常意义上的“集群”。
我们假设,例如,我们想要创建 Alpine Linux IRC 网络。
我们有 irc1 和 irc2 服务器,分别称为 irc1.alpinelab.lan 和 irc2.alpinelab.lan。
先决条件
先决条件是两台安装了 Alpine Linux (v2.5) 的 PC。
我们将要安装的软件包是
- Charybdis
- atheme-iris
这两个软件包都在 edge 中。Charybdis 在 main 中,atheme-iris 在 testing 中。
您可以轻松使用此 pinning edge 仓库
vi /etc/apk/repositories
添加以下行
@edgem https://dl-cdn.alpinelinux.org/alpine/edge/main/
@edget https://dl-cdn.alpinelinux.org/alpine/edge/testing/
然后
apk update
apk add charybdis@edgem
apk add atheme-iris@edgem
配置 Charybdis
cp /etc/charybdis/example.conf /etc/charybdis/ircd.conf
vi /etc/charybdis/ircd.conf
从 /etc/charybdis/reference.conf (文档完善) 开始修改文件。
loadmodule "extensions/chm_operonly.so";
loadmodule "extensions/extb_account.so";
loadmodule "extensions/extb_canjoin.so";
loadmodule "extensions/extb_channel.so";
loadmodule "extensions/extb_extgecos.so";
loadmodule "extensions/extb_oper.so";
loadmodule "extensions/extb_realname.so";
loadmodule "extensions/m_identify.so";
loadmodule "extensions/m_mkpasswd.so";
loadmodule "extensions/m_webirc.so";
loadmodule "extensions/sno_farconnect.so";
loadmodule "extensions/sno_globalkline.so";
loadmodule "extensions/sno_globaloper.so";
serverinfo {
name = "irc1.alpinelab.lan";
sid = "01A";
description = "Alpine Linux IRC Server";
network_name = "Alpine Linux Network";
network_desc = "Alpine Linux IRC network.";
hub = yes;
default_max_clients = 10000;
nicklen = 30;
};
admin {
name = "admin";
description = "Alpine Linux IRC network administrator";
email = "ircadmin@alpinelab.lan";
};
log {
fname_userlog = "logs/userlog";
#fname_fuserlog = "logs/fuserlog";
fname_operlog = "logs/operlog";
#fname_foperlog = "logs/foperlog";
fname_serverlog = "logs/serverlog";
#fname_klinelog = "logs/klinelog";
fname_killlog = "logs/killlog";
fname_operspylog = "logs/operspylog";
#fname_ioerrorlog = "logs/ioerror";
};
class "users" {
ping_time = 2 minutes;
number_per_ident = 10;
number_per_ip = 10;
number_per_ip_global = 50;
cidr_ipv4_bitlen = 24;
cidr_ipv6_bitlen = 64;
number_per_cidr = 200;
max_number = 100;
sendq = 400 kbytes;
};
class "opers" {
ping_time = 5 minutes;
number_per_ip = 10;
max_number = 1000;
sendq = 1 megabyte;
};
class "server" {
ping_time = 5 minutes;
connectfreq = 5 minutes;
max_number = 10;
sendq = 4 megabytes;
};
listen {
defer_accept = yes;
port = 5000, 6665 .. 6669;
sslport = 6697;
};
auth {
user = "*@*";
class = "users";
};
privset "local_op" {
privs = oper:local_kill, oper:operwall;
};
privset "server_bot" {
extends = "local_op";
privs = oper:kline, oper:remoteban, snomask:nick_changes;
};
privset "global_op" {
extends = "local_op";
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
oper:resv, oper:mass_notice, oper:remoteban;
};
privset "admin" {
extends = "global_op";
privs = oper:admin, oper:die, oper:rehash, oper:spy;
};
operator "ircadmin" {
user = "*@*";
password = "MyStrongPassword";
snomask = "+Zbfkrsuy";
flags = ~encrypted;
privset = "admin";
};
connect "irc2.alpinelab.lan" {
host="10.0.2.10";
send_password = "Password_To_Server";
accept_password = "Password_From_Server";
port = 6666;
hub_mask = "*";
class = "server";
flags = compressed, topicburst, autoconn;
};
service {
name = "services.int";
};
cluster {
name = "*.alpinelab.lan";
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
};
shared {
oper = "*@*", "*";
flags = all, rehash;
};
channel {
use_invex = yes;
use_except = yes;
use_forward = yes;
use_knock = yes;
knock_delay = 5 minutes;
knock_delay_channel = 1 minute;
max_chans_per_user = 15;
max_bans = 100;
max_bans_large = 500;
default_split_user_count = 0;
default_split_server_count = 0;
no_create_on_split = no;
no_join_on_split = no;
burst_topicwho = yes;
kick_on_split_riding = no;
only_ascii_channels = no;
resv_forcepart = yes;
channel_target_change = yes;
disable_local_channels = no;
};
serverhide {
flatten_links = yes;
links_delay = 5 minutes;
hidden = no;
disable_hidden = no;
};
blacklist {
host = "rbl.efnetrbl.org";
type = ipv4;
reject_reason = "${nick}, your IP (${ip}) is listed in EFnet's RBL. For assistance, see https://efnetrbl.org/?i=${ip}";
/* Example of a blacklist that supports both IPv4 and IPv6 */
};
alias "NickServ" {
target = "NickServ";
};
alias "ChanServ" {
target = "ChanServ";
};
alias "OperServ" {
target = "OperServ";
};
alias "MemoServ" {
target = "MemoServ";
};
alias "NS" {
target = "NickServ";
};
alias "CS" {
target = "ChanServ";
};
alias "OS" {
target = "OperServ";
};
alias "MS" {
target = "MemoServ";
};
general {
hide_error_messages = opers;
hide_spoof_ips = yes;
default_umodes = "+i";
default_operstring = "is an IRC Operator";
default_adminstring = "is a Server Administrator";
servicestring = "is a Network Service";
disable_fake_channels = no;
tkline_expire_notices = no;
default_floodcount = 10;
failed_oper_notice = yes;
dots_in_ident=2;
min_nonwildcard = 4;
min_nonwildcard_simple = 3;
max_accept = 100;
max_monitor = 100;
anti_nick_flood = yes;
max_nick_time = 20 seconds;
max_nick_changes = 5;
anti_spam_exit_message_time = 5 minutes;
ts_warn_delta = 30 seconds;
ts_max_delta = 5 minutes;
client_exit = yes;
collision_fnc = yes;
resv_fnc = yes;
global_snotices = yes;
dline_with_reason = yes;
kline_delay = 0 seconds;
kline_with_reason = yes;
kline_reason = "K-Lined";
identify_service = "NickServ@services.int";
identify_command = "IDENTIFY";
non_redundant_klines = yes;
warn_no_nline = yes;
use_propagated_bans = yes;
stats_e_disabled = no;
stats_c_oper_only=no;
stats_h_oper_only=no;
stats_y_oper_only=no;
stats_o_oper_only=yes;
stats_P_oper_only=no;
stats_i_oper_only=masked;
stats_k_oper_only=masked;
map_oper_only = no;
operspy_admin_only = no;
operspy_dont_care_user_info = no;
caller_id_wait = 1 minute;
pace_wait_simple = 1 second;
pace_wait = 10 seconds;
short_motd = no;
ping_cookie = no;
connect_timeout = 30 seconds;
default_ident_timeout = 5;
disable_auth = no;
no_oper_flood = yes;
max_targets = 4;
client_flood_max_lines = 20;
use_whois_actually = no;
oper_only_umodes = operwall, locops, servnotice;
oper_umodes = locops, servnotice, operwall, wallop;
oper_snomask = "+s";
burst_away = yes;
nick_delay = 0 seconds; # 15 minutes if you want to enable this
reject_ban_time = 1 minute;
reject_after_count = 3;
reject_duration = 5 minutes;
throttle_duration = 60;
throttle_count = 4;
max_ratelimit_tokens = 30;
away_interval = 30;
};
modules {
path = "/usr/lib/charybdis/modules";
path = "/usr/lib/charybdis/modules/autoload";
};
配置文件的相关部分是
serverinfo {
.
.
sid = "01A"; <----------- This must be unique. You can choose two cipher and one letter.
hub = yes; <----------- This works as an hub. Allows other irc server to connects.
.
.
}
listen {
port = 5000, 6665 .. 6669; <---- Port where charybdis is listening. You can also bind to a specific ip adding "host" directive. If not specifyied charybdis listen on all interfaces.
sslport = 6697; <---- Port for SSL connection. You need a certificate in order to use this feature.
};
operator "ircadmin" {
user = "*@*"; <----------- This is a masq used to match who can become operator. This support CIDR. If you want to allows only 10.0.0.0/24, you can choose "*@10.0.0.*".
password = "MyStrongPassword"; <---- Password used to become IRC Operator.
flags = ~encrypted; <---- Tilde "~" means not. So the password used in this block is not encrypted. Without "~", you need to write the password in this block encrypted.
privset = "admin";
};
connect "irc2.alpinelab.lan" { <----------- Descriptive name of the server you want to connect to.
host="10.0.2.10"; <----------- IP or HOST. They MUST be valid. If hostname, it MUST be an A record.
send_password = "Password_To_Server"; <------- Password you sent TO irc2. In irc2 this is "accept_password".
accept_password = "Password_From_Server"; <------- Password you expect to receive FROM irc2. In irc2 this is "send_password"
flags = compressed, topicburst, autoconn; <------- Autoconn means that irc1 will try automatically to connect to irc2.
};
cluster {
name = "*.alpinelab.lan"; <----------- Masq to indicate what servers can share the information. Those information are written in the following "flags" entry.
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv; <--- Check IRC documentation to understand the meaning of those flags.
};
shared {
oper = "*@*", "*"; <----------- The user@host and the server must be on in order to set klines.
flags = all,rehash; <----------- flags: list of what to allow them to place. All oper will receive this.
};
您甚至可以删除 *Serv 条目。Charybdis 本身不具备此功能,您应该使用外部程序作为机器人来完成此操作(例如 atheme 服务)。
在另一台服务器 irc2 中,配置非常相似。
以下是 /etc/charybdis/ircd.conf 的唯一区别
serverinfo {
sid = "02A";
hub = yes;
}
operator "ircadmin" {
user = "*@*";
password = "MyStrongPassword";
flags = ~encrypted;
privset = "admin";
};
connect "irc1.alpinelab.lan" {
host="10.0.1.10";
send_password = "Password_From_Server";
accept_password = "Password_To_Server";
flags = compressed, topicburst;
};
在 flags 指令的 connect{} 块中,我们没有设置 "autoconn"。这意味着 irc1 将自动连接到 irc2,但反之则不然。
Charybdis 还有许多其他很酷的功能,例如 ssl 连接、垃圾邮件黑名单等等。请在此处查看文档:[1]
在修改完两台服务器中的 ircd.conf 后,修复权限
chown ircd /etc/charybdis/ircd.conf
chmod 400 /etc/charybdis/ircd.conf
配置 Atheme-iris
Atheme-iris 是一个用 AJAX 和 Python 编写的漂亮的 webchat。它是著名的 qwebirc 的一个分支。
配置非常简单。
默认情况下,atheme-iris 将监听所有接口。如果您想修改此行为,请更改 /etc/conf.d/atheme-iris 并设置 atheme 将绑定的 IP 地址。
[execution] args: -n -p 3989 syslog_addr: syslog_port: 514 [irc] server: localhost port: 6667 ssl: false bind_ip: 127.0.0.1 realname: https://irc1.alpinelab.lan ident: nick ident_string: webchat webirc_mode: webirc webirc_password: fish [athemeengine] # Leave this unset to disable all Atheme integration. xmlrpc_path: chan_list_enabled: true chan_list_max_age: 120 chan_list_count: 3 [feedbackengine] from: moo@moo.com to: moo@moo.com smtp_host: 127.0.0.1 smtp_port: 25 [frontend] base_url: <nowiki>http://irc1.alpinelab.lan:9090</nowiki< network_name: AlpineLinux app_title: %(network_name)s Web IRC extra_html: initial_nick: prompt: true chan_prompt: true chan_autoconnect: true static_base_url: / dynamic_base_url: / [atheme] # Even if we don't use nickserv, disabling it cause atheme-iris to not work. # Look at https://github.com/atheme/iris/issues/12 nickserv_login: true chan_list_on_start: true chan_list_cloud_view: false [ui] dedicated_msg_window: false dedicated_notice_window: false hide_joinparts: false simple_color: false fg_color: DDDDDD fg_sec_color: 999999 bg_color: 111111 lastpos_line: true nick_click_query: false nick_colors: false nick_status: false flash_on_mention: false beep_on_mention: false [adminengine] hosts: 127.0.0.1 [proxy] forwarded_for_header: forwarded_for_ips: 127.0.0.1 [tuneback] update_freq: 0.5 maxbuflen: 100000 maxsubscriptions: 1 maxlinelen: 600 dns_timeout: 5 http_ajax_request_timeout: 30 http_request_timeout: 5
在 [execution] 块中,参数将被 /etc/conf.d/atheme-iris 设置覆盖。
在 irc2.alpinelab.lan 中复制相同的配置。
但在 irc2 服务器中,将条目 irc1.alpinelab.lan 更改为 irc2.alpinelab.lan。
Atheme-iris 将根据此指令连接到 127.0.0.1 ip 上的 charybdis
server: localhost
就这样。
现在,您可以使用一个浏览器访问 http://irc1.alpinelab.lan:9090,另一个浏览器访问 http://irc2.alpinelab.lan:9090。
使用两个不同的用户登录到同一个频道。
您应该在两个 web 客户端上都看到这两个用户。
聊天愉快。
注意
当您登录到 webchat 时,您将看到 "webchat@127.0.0.1"。
如果您想知道如何将 127.0.0.1 更改为欺骗地址,您需要在 charybdis 中添加另一个 auth{} 块。有关详细信息,请查看 /etc/charybdis/reference.conf。
如果您想要客户端的真实 IP 地址,您需要使用 atheme-iris 设置 cgi:irc,并且 Charybdis 将使用名为 _mwebirc 的模块来“粘合”自身与 atheme-iris。Cgiirc 在 edge/testing 仓库中可用。
如果您想删除出现在 webchat 左上角的 “Menu” 按钮,那么
vim /var/lib/atheme-iris/css/qui.mcss
查找 .dropdown-tab,然后添加 "display: none;" 如下所示
.qwebirc-qui .outertabbar .dropdown-tab {
float: left;
width: 24px;
cursor: pointer;
cursor: hand;
display: none; <---- This is what you need to add.
}
尽情享受吧!
有用的链接
IRC 命令
https://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands
*-Line 标志
