解决方案

解决方案

我正在尝试在运行最小安装的 CentOS 6.10 的无头服务器上使用 OpenVPN 设置 Transmission,理想情况下这些将在我启动系统时启动。

我可以按照以下步骤让一切运行起来这里这里— 但这仅在手动运行脚本(vpn.sh,根据两个教程)时有效。该脚本如下所示:

#!/bin/sh

sudo openvpn --cd /etc/openvpn --config /etc/openvpn/conf.ovpn --script-security 2 --up /etc/openvpn/up.sh

我想补充一点,除了 OpenVPN 和 Transmission 之外,我还有这个 Telegram 机器人这应该在其他一切都完成后开始,所以我的up.sh文件末尾还有一行,如下所示:

#!/bin/sh

/etc/init.d/transmission-daemon stop
/bin/sed s/IP_ADDRESS/$4/ /var/lib/transmission/.config/transmission/settings_template.json > /var/lib/transmission/.config/transmission/settings.json
/etc/init.d/transmission-daemon start
/etc/init.d/transmission-telegram start

理想情况下,我能够做一些更像这个帖子概述,尽管我并不特别挑剔是否所有流量都通过 VPN 还是只有 torrent 流量:

  1. 开机时启动 OpenVPN(联网后);
  2. 如果VPN连接连通,则配置Transmission通过它;
  3. 如果成功,运行 Transmission(和 Telegram 机器人);
  4. 如果 VPN 在任何时候出现故障,也请优雅地关闭 Transmission(和 Telegram 机器人)。

我尝试按照该帖子中概述的步骤进行操作,但由于某种原因,我无法让事件transmission-vpn-up发生(由route-up.sh教程中的脚本触发)并且始终得到initctl: Event failed.我无法通过遵循帖子中的步骤或将脚本的内容手动传递到命令行来发出事件。route-up.sh,根据 Ask Ubuntu 上的帖子,看起来像这样:

#! /bin/bash

/sbin/initctl emit transmission-vpn-up VPN_GATEWAY=$route_vpn_gateway LOCAL_IP=$ifconfig_local

但是,如果我将 的内容传递down.sh到命令行,则不会收到此类错误:

/sbin/initctl emit transmission-vpn-down

尝试过使用sudo和不使用它。

有没有一种简单的方法可以让我完成这一切?我是否遗漏了一些东西,特别是在 AU 上的其他教程中指定的emit内容transmission-vpn-up,你知道,因为这是针对 Ubuntu 而不是 CentOS 的教程?

或者,让vpn.sh(本文中的第一块代码)在启动时运行会更容易吗?如果 VPN 出现故障,这会是同样整洁或优雅的,但它会起到作用。


快速更新:

我上面提到的 Ask Ubuntu 教程,特别是在/etc/init/transmission-up.conf尝试使用时/usr/sbin/ufw,我在 CentOS 中没有 - 因此出现了原始的Event failed错误消息。我暂时注释掉了这些位,现在我没有任何错误消息。

然而,即使没有任何错误消息并且 VPN 已启动并运行,似乎还有其他问题发生,因为传输从未启动...有关我可以在哪里查看的任何提示吗?

答案1

解决方案

以下是关于这个问题的一些详细方面和解决方案(注意centos 6没有使用systemd,centos在v7上切换到systemd)

centos 7 的解决方案

启动时设置 OpenVPN:

我们可以使用systemd(实现一个服务)让openvpn在启动时启动,我们需要创建服务,启用它然后启动它。 (启用该服务后将在启动时自动启动

1 - 创建服务:(使用root)

cd /etc/systemd/system
touch openvpn-custom.service
chmod 644 openvpn-custom.service

2 - 打开服务文件:(使用root)

/etc/systemd/system/openvpn-custom.service使用您使用的文本编辑器打开示例nano openvpn-custom.service

3 - 编辑和设置服务文件:(使用root)

将以下代码粘贴并修改为/etc/systemd/system/openvpn-custom.service

[Unit]
Description=OpenVPN Custom Setup Script 
After=network.target network-online.target
Wants=network-online.target

[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/full-path-to/your/vpn-script/vpn.sh
ExecStop=/full-path-to/a-scirpt/that-would-stop-openvpn/vpn-stop.sh

[Install]
WantedBy=multi-user.target

4 - 启用并启动服务:(使用root)

systemctl enable openvpn-custom.service
systemctl start openvpn-custom.service

您可以使用以下命令检查服务的状态systemctl status openvpn-custom.service

设置启动时的传输和电报(基于 openvpn 状态):

与 openvpn 解决方案相同,创建一个包含以下代码的新服务(然后启用并启动它)

[Unit]
Description=Application Depending on OpenVPN 
After=network.target network-online.target openvpn-custom.service
Wants=network-online.target openvpn-custom.service

[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/full-path-to/your/ovpn-applications.sh
ExecStop=/full-path-to/a-scirpt/that-would-stop-apps/ovpn-applications-stop.sh

[Install]
WantedBy=multi-user.target

您的 ovpn-applications.sh 看起来像这样

#!/bin/sh
/bin/sed s/IP_ADDRESS/$4/ /var/lib/transmission/.config/transmission/settings_template.json > /var/lib/transmission/.config/transmission/settings.json
/etc/init.d/transmission-daemon start
/etc/init.d/transmission-telegram start

After=openvpn-custom.service并使Wants=openvpn-custom.service该服务依赖于 openvpn,因此如果 openvpn 服务未启动或失败,其他服务将不会启动

centos 6 的解决方案

启动时设置 OpenVPN:

1 - 创建服务:(使用root)

cd /etc/rc.d/init.d
touch openvpn-custom
chmod 755 openvpn-custom

2 - 打开服务文件:(使用root)

/etc/rc.d/init.d/openvpn-custom使用您使用的文本编辑器打开示例nano openvpn-custom

3 - 编辑和设置服务文件:(使用root)

#!/bin/bash
#
# chkconfig: 2345 55 45
# description: Custom openvpn script
# processname: openvpn
#
### BEGIN INIT INFO
# Provides: openvpn
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Short-Description: The openvpn daemon
# Description: The openvpn daemon custom script
### END INIT INFO

#/etc/rc.d/init.d/openvpn-custom
# Source function library.
. /etc/init.d/functions


start() {
        echo -n "Starting custom openvpn... "
        /full-path-to/your/vpn-script/vpn.sh
        return 0
}

stop() {
        echo -n "Shutting down custom openvpn... "
        /full-path-to/a-scirpt/that-would-stop-openvpn/vpn-stop.sh
        return 0
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        ;;
    restart)
        stop
        start
        ;;
    reload)
        ;;
    *)
        echo "Usage: openvpn-custom {start|stop|status|reload|restart}"
 exit 1
        ;;
esac
exit $?

4 - 启用并启动服务:(使用root)

chkconfig openvpn-custom on
service openvpn-custom start

您可以使用以下命令检查服务的状态service openvpn-custom status

如何确保 openvpn 仅在网络就绪时启动

初始化脚本开头的 chkconfig 定义决定了它获得的 S/K 编号。

每个“运行级别”实际上只是一个目录(/etc/rc*.d/)充满了初始化脚本的符号链接(/etc/init.d/)并且这些符号链接以编号的 S 和 K 条目命名。

S表示开始,K表示终止。当 init 进入运行级别时,它从 S01 开始一直到 S99,运行每个 init 脚本来启动该脚本控制的服务。当 init 离开运行级别时,它从 K01 开始一直到 K99,运行每个脚本以停止该脚本控制的服务。

手动检查配置给出了 chkconfig 样式服务定义和 Linux 标准库 (LSB) 样式服务定义的示例。

如果 initscript 定义了两种类型,则 LSB 定义应优先于 chkconfig 定义。

如果您有一个依赖于网络连接的服务,您可以通过给它一个 10 之后的起始编号来确保您的服务在 /etc/rc*.d/S10network 之后启动,或者您可以看到 /etc/init.d/网络具有 LSB 定义提供:$网络,所以你可以使用LSB定义必需启动:$network在你的初始化脚本中。

设置启动时的传输和电报(基于 openvpn 状态):

与 openvpn 解决方案相同,创建一个包含以下代码的新服务(然后启用并启动它)(/etc/rc.d/init.d/openvpn-apps)

#!/bin/bash
#
# chkconfig: 2345 55 45
# description: Custom openvpn-apps script
# processname: openvpn-apps
#
### BEGIN INIT INFO
# Provides: openvpn-apps
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Short-Description: The openvpn-apps daemon
# Description: The openvpn daemon custom script
### END INIT INFO
#/etc/rc.d/init.d/openvpn-apps

# Source function library.
. /etc/init.d/functions


start() {
        echo -n "Starting custom openvpn... "
        /full-path-to/your/apps.sh
        return 0
}

stop() {
        echo -n "Shutting down custom openvpn... "
        /full-path-to/your/stop-apps.sh
        return 0
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        ;;
    restart)
        stop
        start
        ;;
    reload)
        ;;
    *)
        echo "Usage: openvpn-apps {start|stop|status|reload|restart}"
 exit 1
        ;;
esac
exit $?

你的apps.sh看起来像这样

#!/bin/sh
/bin/sed s/IP_ADDRESS/$4/ /var/lib/transmission/.config/transmission/settings_template.json > /var/lib/transmission/.config/transmission/settings.json
/etc/init.d/transmission-daemon start
/etc/init.d/transmission-telegram start

要使你的 apps.sh 依赖于 openvpn 状态,你可以首先延迟 apps.sh 的启动:sleep 或者编写一个 bash 循环,用 ps 检查 openvpn或者检查 openvn 网关的 ping 结果(在 apps.sh 中)或者service openvpn-custom status你可以检查(在apps.sh中)的结果

解决方案(6 和 7)注释:

故障安全openvpn:

您可以设置一个“故障安全”,以便在 openvpn 不工作时使网络关闭,从而在 vpn 不工作时防止连接泄漏,您可以使用或者解决方案

强制应用程序使用特定接口:

如果您的 openvpn 设置是对整个系统进行隧道/路由;没有必要这样做,但如果您不通过 openvpn 接口路由所有流量,您可以代理/绑定/强制您的应用程序(传输/电报)使用 vpn;在 Linux 下,有多种解决方案将应用程序绑定到特定接口,每种解决方案都有其优点和缺点unix stackexchange 答案详细解释大多数可用的可能性

答案2

就您的情况而言,我认为您也可能会尽可能坚持标准程序。

从一个开始原始的CentOS 6.10最小的ISO 安装,我将按如下步骤进行:

第一的,使能够无限制的 OpenVPN:CentoOS 6 附带了一个股票 SELinux 策略,默认情况下/usr/sbin/openvpn以受限模式运行二进制文件,基本上只允许它进行网络设置,从而阻止任何帮助程序脚本执行任何有用的操作。然而,CentOS 6 还提供了一种简单的设置来启用不受限制的 OpenVPN。作为超级用户跑步:

setsebool -P openvpn_run_unconfined on

请稍等几秒钟,因为可能需要一段时间。

可能一旦一切正常,想将其恢复到受限模式。我稍后会回来讨论一些可行的方法。

然后,要继续进行基本设置,安装将 EPEL 存储库添加到系统的 yum 中:

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

这为您的系统的 yum 提供了一个存储库,该存储库为 CentOS 6 打包的 openvpn 和传输提供 RPM。

之后你可以:

yum install openvpn transmission-daemon

然后安装机器人transmission-telegram就像你已经做过的那样。只需确保将其放置在 中指定的目录中即可$PATH。考虑到 CentOS 6 的 SELinux 政策,/usr/local/bin可能是一个不错的选择。

请注意我无法真正详细介绍 Telegram 机器人的细节,因为我对它一无所知,甚至无法测试它,因为我根本不使用 Telegram。)

然后制作像这样的脚本openvpn-transmission-up.sh

#!/bin/bash

PATH+=":/sbin:/usr/sbin"
service transmission-daemon start
service transmission-daemon status && telegram-bot-start.sh

telegram-bot-start.sh只是一个假设的包装器,用于运行启动 Telegram 机器人的实际命令,并且仅在 Transmission-daemon 成功启动时才执行。如果可以将直接命令作为单行命令放在&&.

然后还有制作像这样的脚本openvpn-transmission-down.sh

#!/bin/bash

PATH+=":/sbin:/usr/sbin"
telegram-bot-stop.sh
service transmission-daemon stop || true

在这里,您也可以使用直接命令来停止 Telegram 机器人,而不是telegram-bot-stop.sh包装器,在这种情况下,即使它们实际上是命令序列。

然后制作上面两个脚本可以运行:

chmod +x openvpn-transmission-up.sh openvpn-transmission-down.sh

地方它们位于/etc/openvpn/scripts目录中(再次遵守 CentoOS SELinux 政策)。如果您还没有该目录,请创建该目录。

然后将您自己的 OpenVPN 配置放入/etc/openvpn.此类文件可以随意命名,但必须有.conf后缀。

确保.conf该文件中有以下几行:

script-security 2
route-up scripts/openvpn-transmission-up.sh
route-pre-down scripts/openvpn-transmission-down.sh

如果您已经有route-uproute-pre-down脚本,则只需将您预先存在的脚本分别与上述脚本合并,但请确保将它们放入/etc/openvpn/scripts.

上述设置可确保您的 Transmission 和 Telegram 机器人始终遵循 VPN 隧道的命运。

最后openvpn 在启动时运行:

chkconfig openvpn on

最后一项设置依赖于 OpenVPN 的 RPM 包附带的设置,这使得它仅在常规网络成功启动后运行。

请注意,我认为您实际上不需要配置 Transmission,因为其 RPM 包附带的默认配置应该足够了。但是,如果您希望重复使用sed 命令来设置 IP_ADDRESS,请在启动 Transmission-daemon 之前将该sed命令放入脚本中。openvpn-transmission-up.sh无论如何,通常最好使用$ifconfig_local而不是$4.

此时您应该已准备就绪。您可以通过简单的service openvpn后跟start 或stop等来测试它restart 。或者只需重新启动您的无头服务器。

笔记如果您的 VPN 提供商要求通过用户名和密码进行身份验证,您需要将它们放入文件中的两行中。该文件应驻留在/etc/openvpn符合 SELinux 政策的位置。然后包含auth-user-pass /etc/openvpn/credentials-file到您的 openvpn.conf文件中。如果您不这样做,CentOS 将在启动期间停止,等待交互式输入凭据,或者 OpenVPN 可能会拒绝启动。


关于(重新)强化上述设置,根据您的喜好,您可能会感到高兴:到目前为止,该设置利用了 CentOS 预安装的允许设置,包括允许 OpenVPN 在较少限制下运行的设置,它基本上允许帮助程序脚本自由执行系统上可用的二进制文件。尽管这听起来很宽松,但它仍然比根本没有 SELinux 受到更多限制,并且通过这种方式,Transmission 和 Telegram 机器人的运行都会比其库存(或手动)安装所允许的限制更多一些。

如果您希望将 OpenVPN 重新置于受限操作中,那么利用 CentOS 6 实际上使用 Upstart 作为它的事实仍然相当容易,/sbin/init尽管它的大部分引导操作依赖于旧版 SysVinit 风格的脚本。但是您需要一些额外的步骤:

  1. 一个(幸运的是简单的)自定义 SELinux 策略,至少允许 OpenVPN 与 Upstart 对话,以便要求后者启动 Transmission 和 Telegram 机器人
  2. 几个(简单的)Upstart 作业,用于通过其遗留脚本启动 Transmission 以及 Telegram 机器人

开始,OpenVPN 回到受限模式:

setsebool -P openvpn_run_unconfined off

现在,如果您启动 OpenVPN,帮助程序脚本将无法启动 Transmission 和 Telegram 机器人。

因此,自定义 SELinux 策略:

制作一个名为openvpn-talk-upstart.te 确切地如下:

module openvpn-talk-upstart.mod 1.0;

require {
        type openvpn_t;
        type init_t;
        class unix_stream_socket connectto;
}

allow openvpn_t init_t:unix_stream_socket connectto;

然后跑步以下命令:

checkmodule -m -M -o openvpn-talk-upstart.mod openvpn-talk-upstart.te
semodule_package -o openvpn-talk-upstart.pp -m openvpn-talk-upstart.mod
semodule -i openvpn-talk-upstart.pp

最后一个命令可能需要一些时间。

然后是新贵职位:

制作/etc/init/transmission-up.conf如下文件:

task

exec service transmission-daemon start

/etc/init/transmission-down.conf如下文件:

task

exec service transmission-daemon stop

然后你需要Telegram 机器人也有新贵职位。

为了与我的示例保持一致,我坚持使用假设的脚本方法,因此名为/etc/init/telegram-bot-up.conf和 的作业文件/etc/init/telegram-bot-down.conf将类似于传输文件,只是将execed 命令分别转换为/usr/local/bin/telegram-bot-start.sh/usr/local/bin/telegram-bot-stop.sh

请注意,这里,根据您对 Upstart 的信心,您还可以将相关命令直接放在作业文件中,在script ... end-script关键字中代替关键字exec,或者您甚至可以通过一个 Upstart 作业文件创建一个完全由 Upstart 控制的守护进程(但不是task类型)如果你愿意的话。

在这之后,制作OpenVPN 帮助openvpn-transmission-up.sh程序脚本/etc/openvpn/scripts如下:

#!/bin/sh

/sbin/start transmission-up && /sbin/start telegram-bot-up

剧本openvpn-transmission-down.sh

#!/bin/sh

/sbin/start telegram-bot-down
/sbin/start transmission-down || true

笔记/sbin/start即使它实际上是“向下”操作,也使用该命令。

现在一切都应该可以正常工作,OpenVPN 处于其原始受限(即更安全)模式,但 Transmission 和 Telegram 机器人都处于标准“免费”(即不太安全)模式。


如果您希望进一步强化后两者,那么您需要在受限的 SELinux 环境中运行它们,例如 OpenVPN 的环境,然后仔细分析该/var/log/audit/audit.log文件,以便精确调整 SELinux 策略。有一些工具可以帮助您,即包audit2allow中提供的命令policycoreutils-python

audit.log您可以在宽容模式下对来自 SELinux 的命令运行该命令(请参阅/etc/sysconfig/selinux文件),但这可能最终会允许太多。否则,您可以在audit.log来自常规执行 SELinux 的系统上运行它,逐步执行,直到您最终获得工作设置。通过后一种方式,您可以确保只允许不超过实际需要的内容。

的输出audit2allow -a -m ...必须馈送到checkmodule -m -M -o ...,然后将后者的输出馈送到semodule_package -o ... -m ...,最后semodule -i馈送到 生成的文件的a semodule_package。在分析的每个步骤中进行迭代。

它可以是一个非常这是一项漫长的任务,即使您进行了工作设置,也可能只是最初如此:在某些时候您可能会在稍后遇到意外的“权限被拒绝”问题,例如,当您的 Transmission 或 Telegram Bot 第一次尝试访问时以前从未尝试过的东西。

相关内容