如何设置您自己的 IRC 网络

来自 Alpine Linux
此材料建议删除...

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 标志

https://en.wikipedia.org/wiki/IRCd#K-line